2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_track.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/audioplaylist.h"
53 #include "ardour/audioregion.h"
54 #include "ardour/auditioner.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/bundle.h"
57 #include "ardour/click.h"
58 #include "ardour/configuration.h"
59 #include "ardour/crossfade.h"
60 #include "ardour/cycle_timer.h"
61 #include "ardour/data_type.h"
62 #include "ardour/filename_extensions.h"
63 #include "ardour/io_processor.h"
64 #include "ardour/midi_diskstream.h"
65 #include "ardour/midi_playlist.h"
66 #include "ardour/midi_region.h"
67 #include "ardour/midi_track.h"
68 #include "ardour/named_selection.h"
69 #include "ardour/playlist.h"
70 #include "ardour/plugin_insert.h"
71 #include "ardour/port_insert.h"
72 #include "ardour/processor.h"
73 #include "ardour/recent_sessions.h"
74 #include "ardour/region_factory.h"
75 #include "ardour/return.h"
76 #include "ardour/route_group.h"
77 #include "ardour/send.h"
78 #include "ardour/session.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_metadata.h"
82 #include "ardour/slave.h"
83 #include "ardour/smf_source.h"
84 #include "ardour/source_factory.h"
85 #include "ardour/tape_file_matcher.h"
86 #include "ardour/tempo.h"
87 #include "ardour/utils.h"
92 using namespace ARDOUR;
94 using boost::shared_ptr;
96 bool Session::_disable_all_loaded_plugins = false;
98 sigc::signal<void,std::string> Session::Dialog;
99 sigc::signal<int> Session::AskAboutPendingState;
100 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::StartTimeChanged;
105 sigc::signal<void> Session::EndTimeChanged;
106 sigc::signal<void> Session::AutoBindingOn;
107 sigc::signal<void> Session::AutoBindingOff;
108 sigc::signal<void, std::string, std::string> Session::Exported;
110 Session::Session (AudioEngine &eng,
111 const string& fullpath,
112 const string& snapshot_name,
119 _requested_return_frame (-1),
120 _scratch_buffers(new BufferSet()),
121 _silent_buffers(new BufferSet()),
122 _mix_buffers(new BufferSet()),
124 _mmc_port (default_mmc_port),
125 _mtc_port (default_mtc_port),
126 _midi_port (default_midi_port),
127 _midi_clock_port (default_midi_clock_port),
128 _session_dir (new SessionDirectory(fullpath)),
129 pending_events (2048),
131 butler_mixdown_buffer (0),
132 butler_gain_buffer (0),
133 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 midi_thread (pthread_t (0)),
136 midi_requests (128), // the size of this should match the midi request pool size
137 diskstreams (new DiskstreamList),
138 routes (new RouteList),
139 auditioner ((Auditioner*) 0),
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 if (!eng.connected()) {
154 throw failed_constructor();
157 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
159 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
160 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
162 first_stage_init (fullpath, snapshot_name);
164 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
167 if (create (new_session, mix_template, compute_initial_length())) {
169 throw failed_constructor ();
173 if (second_stage_init (new_session)) {
175 throw failed_constructor ();
178 store_recent_sessions(_name, _path);
180 bool was_dirty = dirty();
182 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
184 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
187 DirtyChanged (); /* EMIT SIGNAL */
191 Session::Session (AudioEngine &eng,
193 string snapshot_name,
194 AutoConnectOption input_ac,
195 AutoConnectOption output_ac,
196 uint32_t control_out_channels,
197 uint32_t master_out_channels,
198 uint32_t requested_physical_in,
199 uint32_t requested_physical_out,
200 nframes_t initial_length)
206 _requested_return_frame (-1),
207 _scratch_buffers(new BufferSet()),
208 _silent_buffers(new BufferSet()),
209 _mix_buffers(new BufferSet()),
211 _mmc_port (default_mmc_port),
212 _mtc_port (default_mtc_port),
213 _midi_port (default_midi_port),
214 _midi_clock_port (default_midi_clock_port),
215 _session_dir ( new SessionDirectory(fullpath)),
216 pending_events (2048),
218 butler_mixdown_buffer (0),
219 butler_gain_buffer (0),
220 post_transport_work((PostTransportWork)0),
221 _send_smpte_update (false),
222 midi_thread (pthread_t (0)),
224 diskstreams (new DiskstreamList),
225 routes (new RouteList),
226 auditioner ((Auditioner *) 0),
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 if (!eng.connected()) {
240 throw failed_constructor();
243 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
245 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
246 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
248 if (n_physical_inputs) {
249 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
252 if (n_physical_outputs) {
253 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
256 first_stage_init (fullpath, snapshot_name);
258 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
261 if (create (new_session, string(), initial_length)) {
263 throw failed_constructor ();
268 /* set up Master Out and Control Out if necessary */
273 if (control_out_channels) {
274 ChanCount count(DataType::AUDIO, control_out_channels);
275 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut,
276 DataType::AUDIO, count, count));
277 r->set_remote_control_id (control_id++);
282 if (master_out_channels) {
283 ChanCount count(DataType::AUDIO, master_out_channels);
284 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut,
285 DataType::AUDIO, count, count));
286 r->set_remote_control_id (control_id);
290 /* prohibit auto-connect to master, because there isn't one */
291 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
295 add_routes (rl, false);
300 Config->set_input_auto_connect (input_ac);
301 Config->set_output_auto_connect (output_ac);
303 if (second_stage_init (new_session)) {
305 throw failed_constructor ();
308 store_recent_sessions (_name, _path);
310 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
312 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
323 /* if we got to here, leaving pending capture state around
327 remove_pending_capture_state ();
329 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
331 _engine.remove_session ();
333 GoingAway (); /* EMIT SIGNAL */
339 /* clear history so that no references to objects are held any more */
343 /* clear state tree so that no references to objects are held any more */
347 terminate_butler_thread ();
348 //terminate_midi_thread ();
350 if (click_data != default_click) {
351 delete [] click_data;
354 if (click_emphasis_data != default_click_emphasis) {
355 delete [] click_emphasis_data;
360 delete _scratch_buffers;
361 delete _silent_buffers;
364 AudioDiskstream::free_working_buffers();
366 Route::SyncOrderKeys.clear();
368 #undef TRACK_DESTRUCTION
369 #ifdef TRACK_DESTRUCTION
370 cerr << "delete named selections\n";
371 #endif /* TRACK_DESTRUCTION */
372 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
373 NamedSelectionList::iterator tmp;
382 #ifdef TRACK_DESTRUCTION
383 cerr << "delete playlists\n";
384 #endif /* TRACK_DESTRUCTION */
385 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
386 PlaylistList::iterator tmp;
391 (*i)->drop_references ();
396 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
397 PlaylistList::iterator tmp;
402 (*i)->drop_references ();
408 unused_playlists.clear ();
410 #ifdef TRACK_DESTRUCTION
411 cerr << "delete regions\n";
412 #endif /* TRACK_DESTRUCTION */
414 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
415 RegionList::iterator tmp;
420 i->second->drop_references ();
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete routes\n";
429 #endif /* TRACK_DESTRUCTION */
431 RCUWriter<RouteList> writer (routes);
432 boost::shared_ptr<RouteList> r = writer.get_copy ();
433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
434 (*i)->drop_references ();
437 /* writer goes out of scope and updates master */
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete diskstreams\n";
444 #endif /* TRACK_DESTRUCTION */
446 RCUWriter<DiskstreamList> dwriter (diskstreams);
447 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
448 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
449 (*i)->drop_references ();
453 diskstreams.flush ();
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete audio sources\n";
457 #endif /* TRACK_DESTRUCTION */
458 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
459 SourceMap::iterator tmp;
464 i->second->drop_references ();
470 #ifdef TRACK_DESTRUCTION
471 cerr << "delete mix groups\n";
472 #endif /* TRACK_DESTRUCTION */
473 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
474 list<RouteGroup*>::iterator tmp;
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete edit groups\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
488 list<RouteGroup*>::iterator tmp;
498 delete [] butler_mixdown_buffer;
499 delete [] butler_gain_buffer;
501 Crossfade::set_buffer_size (0);
507 Session::set_worst_io_latencies ()
509 _worst_output_latency = 0;
510 _worst_input_latency = 0;
512 if (!_engine.connected()) {
516 boost::shared_ptr<RouteList> r = routes.reader ();
518 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
519 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
520 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
525 Session::when_engine_running ()
527 string first_physical_output;
529 /* we don't want to run execute this again */
531 BootMessage (_("Set block size and sample rate"));
533 set_block_size (_engine.frames_per_cycle());
534 set_frame_rate (_engine.frame_rate());
536 BootMessage (_("Using configuration"));
538 Config->map_parameters (mem_fun (*this, &Session::config_changed));
540 /* every time we reconnect, recompute worst case output latencies */
542 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
544 if (synced_to_jack()) {
545 _engine.transport_stop ();
548 if (Config->get_jack_time_master()) {
549 _engine.transport_locate (_transport_frame);
557 _click_io.reset (new ClickIO (*this, "click"));
559 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
561 /* existing state for Click */
563 if (_click_io->set_state (*child->children().front()) == 0) {
565 _clicking = Config->get_clicking ();
569 error << _("could not setup Click I/O") << endmsg;
575 /* default state for Click: dual-mono to first 2 physical outputs */
577 for (int physport = 0; physport < 2; ++physport) {
578 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
580 if (physical_output.length()) {
581 if (_click_io->add_output_port (physical_output, this)) {
582 // relax, even though its an error
587 if (_click_io->n_outputs () > ChanCount::ZERO) {
588 _clicking = Config->get_clicking ();
593 catch (failed_constructor& err) {
594 error << _("cannot setup Click I/O") << endmsg;
597 BootMessage (_("Compute I/O Latencies"));
599 set_worst_io_latencies ();
602 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
605 BootMessage (_("Set up standard connections"));
607 /* Create a set of Bundle objects that map
608 to the physical I/O currently available. We create both
609 mono and stereo bundles, so that the common cases of mono
610 and stereo tracks get bundles to put in their mixer strip
611 in / out menus. There may be a nicer way of achieving that;
612 it doesn't really scale that well to higher channel counts */
614 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
616 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
618 shared_ptr<Bundle> c (new Bundle (buf, true));
619 c->add_channel (_("mono"));
620 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
625 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
626 if (np + 1 < n_physical_outputs) {
628 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
629 shared_ptr<Bundle> c (new Bundle (buf, true));
630 c->add_channel (_("L"));
631 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
632 c->add_channel (_("R"));
633 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
639 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
641 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
643 shared_ptr<Bundle> c (new Bundle (buf, false));
644 c->add_channel (_("mono"));
645 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
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));
667 /* create master/control ports */
670 /* force the master to ignore any later call to this */
671 if (_master_out->pending_state_node) {
672 _master_out->ports_became_legal();
675 /* no panner resets till we are through */
676 _master_out->defer_pan_reset ();
679 _master_out->set_input_minimum(ChanCount(DataType::AUDIO, n_physical_inputs));
680 _master_out->set_output_minimum(ChanCount(DataType::AUDIO, n_physical_outputs));
681 _master_out->ensure_io (
682 _master_out->input_minimum (), _master_out->output_minimum (),
685 _master_out->allow_pan_reset ();
690 BootMessage (_("Setup signal flow and plugins"));
694 /* catch up on send+insert cnts */
696 BootMessage (_("Catch up with send/insert state"));
700 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
703 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
704 if (id > insert_cnt) {
712 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
715 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
723 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
725 /* hook us up to the engine */
727 BootMessage (_("Connect to engine"));
729 _engine.set_session (this);
733 Session::hookup_io ()
735 /* stop graph reordering notifications from
736 causing resorts, etc.
739 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
742 if (auditioner == 0) {
744 /* we delay creating the auditioner till now because
745 it makes its own connections to ports.
746 the engine has to be running for this to work.
750 auditioner.reset (new Auditioner (*this));
753 catch (failed_constructor& err) {
754 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
758 /* Tell all IO objects to create their ports */
763 vector<string> cports;
765 _control_out->ensure_io(
766 _control_out->input_minimum(), _control_out->output_minimum(),
769 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
771 for (uint32_t n = 0; n < ni; ++n) {
772 cports.push_back (_control_out->input(n)->name());
775 boost::shared_ptr<RouteList> r = routes.reader ();
777 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
778 (*x)->set_control_outs (cports);
782 /* load bundles, which we may have postponed earlier on */
783 if (_bundle_xml_node) {
784 load_bundles (*_bundle_xml_node);
785 delete _bundle_xml_node;
788 /* Tell all IO objects to connect themselves together */
790 IO::enable_connecting ();
792 /* Now reset all panners */
794 IO::reset_panners ();
796 /* Anyone who cares about input state, wake up and do something */
798 IOConnectionsComplete (); /* EMIT SIGNAL */
800 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
803 /* now handle the whole enchilada as if it was one
809 /* update mixer solo state */
815 Session::playlist_length_changed ()
817 /* we can't just increase end_location->end() if pl->get_maximum_extent()
818 if larger. if the playlist used to be the longest playlist,
819 and its now shorter, we have to decrease end_location->end(). hence,
820 we have to iterate over all diskstreams and check the
821 playlists currently in use.
827 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
829 boost::shared_ptr<Playlist> playlist;
831 if ((playlist = dstream->playlist()) != 0) {
832 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
835 /* see comment in playlist_length_changed () */
840 Session::record_enabling_legal () const
842 /* this used to be in here, but survey says.... we don't need to restrict it */
843 // if (record_status() == Recording) {
847 if (Config->get_all_safe()) {
854 Session::reset_input_monitor_state ()
856 if (transport_rolling()) {
858 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
860 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
861 if ((*i)->record_enabled ()) {
862 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
863 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
867 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
869 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
870 if ((*i)->record_enabled ()) {
871 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
872 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
879 Session::auto_punch_start_changed (Location* location)
881 replace_event (Event::PunchIn, location->start());
883 if (get_record_enabled() && Config->get_punch_in()) {
884 /* capture start has been changed, so save new pending state */
885 save_state ("", true);
890 Session::auto_punch_end_changed (Location* location)
892 nframes_t when_to_stop = location->end();
893 // when_to_stop += _worst_output_latency + _worst_input_latency;
894 replace_event (Event::PunchOut, when_to_stop);
898 Session::auto_punch_changed (Location* location)
900 nframes_t when_to_stop = location->end();
902 replace_event (Event::PunchIn, location->start());
903 //when_to_stop += _worst_output_latency + _worst_input_latency;
904 replace_event (Event::PunchOut, when_to_stop);
908 Session::auto_loop_changed (Location* location)
910 replace_event (Event::AutoLoop, location->end(), location->start());
912 if (transport_rolling() && play_loop) {
914 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
916 if (_transport_frame > location->end()) {
917 // relocate to beginning of loop
918 clear_events (Event::LocateRoll);
920 request_locate (location->start(), true);
923 else if (Config->get_seamless_loop() && !loop_changing) {
925 // schedule a locate-roll to refill the diskstreams at the
927 loop_changing = true;
929 if (location->end() > last_loopend) {
930 clear_events (Event::LocateRoll);
931 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
938 last_loopend = location->end();
942 Session::set_auto_punch_location (Location* location)
946 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
947 auto_punch_start_changed_connection.disconnect();
948 auto_punch_end_changed_connection.disconnect();
949 auto_punch_changed_connection.disconnect();
950 existing->set_auto_punch (false, this);
951 remove_event (existing->start(), Event::PunchIn);
952 clear_events (Event::PunchOut);
953 auto_punch_location_changed (0);
962 if (location->end() <= location->start()) {
963 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
967 auto_punch_start_changed_connection.disconnect();
968 auto_punch_end_changed_connection.disconnect();
969 auto_punch_changed_connection.disconnect();
971 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
972 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
973 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
975 location->set_auto_punch (true, this);
978 auto_punch_changed (location);
980 auto_punch_location_changed (location);
984 Session::set_auto_loop_location (Location* location)
988 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
989 auto_loop_start_changed_connection.disconnect();
990 auto_loop_end_changed_connection.disconnect();
991 auto_loop_changed_connection.disconnect();
992 existing->set_auto_loop (false, this);
993 remove_event (existing->end(), Event::AutoLoop);
994 auto_loop_location_changed (0);
1003 if (location->end() <= location->start()) {
1004 error << _("Session: you can't use a mark for auto loop") << endmsg;
1008 last_loopend = location->end();
1010 auto_loop_start_changed_connection.disconnect();
1011 auto_loop_end_changed_connection.disconnect();
1012 auto_loop_changed_connection.disconnect();
1014 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1015 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1016 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1018 location->set_auto_loop (true, this);
1020 /* take care of our stuff first */
1022 auto_loop_changed (location);
1024 /* now tell everyone else */
1026 auto_loop_location_changed (location);
1030 Session::locations_added (Location* ignored)
1036 Session::locations_changed ()
1038 _locations.apply (*this, &Session::handle_locations_changed);
1042 Session::handle_locations_changed (Locations::LocationList& locations)
1044 Locations::LocationList::iterator i;
1046 bool set_loop = false;
1047 bool set_punch = false;
1049 for (i = locations.begin(); i != locations.end(); ++i) {
1053 if (location->is_auto_punch()) {
1054 set_auto_punch_location (location);
1057 if (location->is_auto_loop()) {
1058 set_auto_loop_location (location);
1062 if (location->is_start()) {
1063 start_location = location;
1065 if (location->is_end()) {
1066 end_location = location;
1071 set_auto_loop_location (0);
1074 set_auto_punch_location (0);
1081 Session::enable_record ()
1083 /* XXX really atomic compare+swap here */
1084 if (g_atomic_int_get (&_record_status) != Recording) {
1085 g_atomic_int_set (&_record_status, Recording);
1086 _last_record_location = _transport_frame;
1087 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1089 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1090 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1091 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1092 if ((*i)->record_enabled ()) {
1093 (*i)->monitor_input (true);
1098 RecordStateChanged ();
1103 Session::disable_record (bool rt_context, bool force)
1107 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1109 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1110 g_atomic_int_set (&_record_status, Disabled);
1112 if (rs == Recording) {
1113 g_atomic_int_set (&_record_status, Enabled);
1117 // FIXME: timestamp correct? [DR]
1118 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1119 // does this /need/ to be sent in all cases?
1121 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1123 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1124 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1126 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1127 if ((*i)->record_enabled ()) {
1128 (*i)->monitor_input (false);
1133 RecordStateChanged (); /* emit signal */
1136 remove_pending_capture_state ();
1142 Session::step_back_from_record ()
1144 /* XXX really atomic compare+swap here */
1145 if (g_atomic_int_get (&_record_status) == Recording) {
1146 g_atomic_int_set (&_record_status, Enabled);
1148 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1149 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1151 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1152 if ((*i)->record_enabled ()) {
1153 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1154 (*i)->monitor_input (false);
1162 Session::maybe_enable_record ()
1164 g_atomic_int_set (&_record_status, Enabled);
1166 /* this function is currently called from somewhere other than an RT thread.
1167 this save_state() call therefore doesn't impact anything.
1170 save_state ("", true);
1172 if (_transport_speed) {
1173 if (!Config->get_punch_in()) {
1177 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1178 RecordStateChanged (); /* EMIT SIGNAL */
1185 Session::audible_frame () const
1191 /* the first of these two possible settings for "offset"
1192 mean that the audible frame is stationary until
1193 audio emerges from the latency compensation
1196 the second means that the audible frame is stationary
1197 until audio would emerge from a physical port
1198 in the absence of any plugin latency compensation
1201 offset = _worst_output_latency;
1203 if (offset > current_block_size) {
1204 offset -= current_block_size;
1206 /* XXX is this correct? if we have no external
1207 physical connections and everything is internal
1208 then surely this is zero? still, how
1209 likely is that anyway?
1211 offset = current_block_size;
1214 if (synced_to_jack()) {
1215 tf = _engine.transport_frame();
1217 tf = _transport_frame;
1222 if (!non_realtime_work_pending()) {
1226 /* check to see if we have passed the first guaranteed
1227 audible frame past our last start position. if not,
1228 return that last start point because in terms
1229 of audible frames, we have not moved yet.
1232 if (_transport_speed > 0.0f) {
1234 if (!play_loop || !have_looped) {
1235 if (tf < _last_roll_location + offset) {
1236 return _last_roll_location;
1244 } else if (_transport_speed < 0.0f) {
1246 /* XXX wot? no backward looping? */
1248 if (tf > _last_roll_location - offset) {
1249 return _last_roll_location;
1261 Session::set_frame_rate (nframes_t frames_per_second)
1263 /** \fn void Session::set_frame_size(nframes_t)
1264 the AudioEngine object that calls this guarantees
1265 that it will not be called while we are also in
1266 ::process(). Its fine to do things that block
1270 _base_frame_rate = frames_per_second;
1274 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1278 // XXX we need some equivalent to this, somehow
1279 // SndFileSource::setup_standard_crossfades (frames_per_second);
1283 /* XXX need to reset/reinstantiate all LADSPA plugins */
1287 Session::set_block_size (nframes_t nframes)
1289 /* the AudioEngine guarantees
1290 that it will not be called while we are also in
1291 ::process(). It is therefore fine to do things that block
1296 current_block_size = nframes;
1298 ensure_buffers(_scratch_buffers->available());
1300 delete [] _gain_automation_buffer;
1301 _gain_automation_buffer = new gain_t[nframes];
1303 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1305 boost::shared_ptr<RouteList> r = routes.reader ();
1307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1308 (*i)->set_block_size (nframes);
1311 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1312 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1313 (*i)->set_block_size (nframes);
1316 set_worst_io_latencies ();
1321 Session::set_default_fade (float steepness, float fade_msecs)
1324 nframes_t fade_frames;
1326 /* Don't allow fade of less 1 frame */
1328 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1335 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1339 default_fade_msecs = fade_msecs;
1340 default_fade_steepness = steepness;
1343 // jlc, WTF is this!
1344 Glib::RWLock::ReaderLock lm (route_lock);
1345 AudioRegion::set_default_fade (steepness, fade_frames);
1350 /* XXX have to do this at some point */
1351 /* foreach region using default fade, reset, then
1352 refill_all_diskstream_buffers ();
1357 struct RouteSorter {
1358 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1359 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1361 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1364 if (r1->fed_by.empty()) {
1365 if (r2->fed_by.empty()) {
1366 /* no ardour-based connections inbound to either route. just use signal order */
1367 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1369 /* r2 has connections, r1 does not; run r1 early */
1373 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1380 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1382 shared_ptr<Route> r2;
1384 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1385 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1389 /* make a copy of the existing list of routes that feed r1 */
1391 set<shared_ptr<Route> > existing = r1->fed_by;
1393 /* for each route that feeds r1, recurse, marking it as feeding
1397 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1400 /* r2 is a route that feeds r1 which somehow feeds base. mark
1401 base as being fed by r2
1404 rbase->fed_by.insert (r2);
1408 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1412 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1416 /* now recurse, so that we can mark base as being fed by
1417 all routes that feed r2
1420 trace_terminal (r2, rbase);
1427 Session::resort_routes ()
1429 /* don't do anything here with signals emitted
1430 by Routes while we are being destroyed.
1433 if (_state_of_the_state & Deletion) {
1440 RCUWriter<RouteList> writer (routes);
1441 shared_ptr<RouteList> r = writer.get_copy ();
1442 resort_routes_using (r);
1443 /* writer goes out of scope and forces update */
1448 Session::resort_routes_using (shared_ptr<RouteList> r)
1450 RouteList::iterator i, j;
1452 for (i = r->begin(); i != r->end(); ++i) {
1454 (*i)->fed_by.clear ();
1456 for (j = r->begin(); j != r->end(); ++j) {
1458 /* although routes can feed themselves, it will
1459 cause an endless recursive descent if we
1460 detect it. so don't bother checking for
1468 if ((*j)->feeds (*i)) {
1469 (*i)->fed_by.insert (*j);
1474 for (i = r->begin(); i != r->end(); ++i) {
1475 trace_terminal (*i, *i);
1482 cerr << "finished route resort\n";
1484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1485 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1492 list<boost::shared_ptr<MidiTrack> >
1493 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1495 char track_name[32];
1496 uint32_t track_id = 0;
1499 RouteList new_routes;
1500 list<boost::shared_ptr<MidiTrack> > ret;
1501 //uint32_t control_id;
1503 // FIXME: need physical I/O and autoconnect stuff for MIDI
1505 /* count existing midi tracks */
1508 shared_ptr<RouteList> r = routes.reader ();
1510 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1511 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1512 if (!(*i)->is_hidden()) {
1514 //channels_used += (*i)->n_inputs().n_midi();
1520 vector<string> physinputs;
1521 vector<string> physoutputs;
1523 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1524 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1526 // control_id = ntracks() + nbusses();
1530 /* check for duplicate route names, since we might have pre-existing
1531 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1532 save, close,restart,add new route - first named route is now
1540 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1542 if (route_by_name (track_name) == 0) {
1546 } while (track_id < (UINT_MAX-1));
1548 shared_ptr<MidiTrack> track;
1551 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1553 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1554 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1560 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1564 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1565 port = physinputs[(channels_used+x)%nphysical_in];
1568 if (port.length() && track->connect_input (track->input (x), port, this)) {
1574 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1578 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1579 port = physoutputs[(channels_used+x)%nphysical_out];
1580 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1582 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1586 if (port.length() && track->connect_output (track->output (x), port, this)) {
1591 channels_used += track->n_inputs ().n_midi();
1595 track->midi_diskstream()->non_realtime_input_change();
1597 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1598 //track->set_remote_control_id (control_id);
1600 new_routes.push_back (track);
1601 ret.push_back (track);
1604 catch (failed_constructor &err) {
1605 error << _("Session: could not create new midi track.") << endmsg;
1608 /* we need to get rid of this, since the track failed to be created */
1609 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1612 RCUWriter<DiskstreamList> writer (diskstreams);
1613 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1614 ds->remove (track->midi_diskstream());
1621 catch (AudioEngine::PortRegistrationFailure& pfe) {
1623 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;
1626 /* we need to get rid of this, since the track failed to be created */
1627 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1630 RCUWriter<DiskstreamList> writer (diskstreams);
1631 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1632 ds->remove (track->midi_diskstream());
1643 if (!new_routes.empty()) {
1644 add_routes (new_routes, false);
1645 save_state (_current_snapshot_name);
1651 list<boost::shared_ptr<AudioTrack> >
1652 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1654 char track_name[32];
1655 uint32_t track_id = 0;
1657 uint32_t channels_used = 0;
1659 RouteList new_routes;
1660 list<boost::shared_ptr<AudioTrack> > ret;
1661 uint32_t control_id;
1663 /* count existing audio tracks */
1666 shared_ptr<RouteList> r = routes.reader ();
1668 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1669 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1670 if (!(*i)->is_hidden()) {
1672 channels_used += (*i)->n_inputs().n_audio();
1678 vector<string> physinputs;
1679 vector<string> physoutputs;
1681 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1682 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1684 control_id = ntracks() + nbusses() + 1;
1688 /* check for duplicate route names, since we might have pre-existing
1689 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1690 save, close,restart,add new route - first named route is now
1698 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1700 if (route_by_name (track_name) == 0) {
1704 } while (track_id < (UINT_MAX-1));
1706 shared_ptr<AudioTrack> track;
1709 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1711 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1712 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1713 input_channels, output_channels)
1718 if (!physinputs.empty()) {
1719 uint32_t nphysical_in = physinputs.size();
1721 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1725 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1726 port = physinputs[(channels_used+x)%nphysical_in];
1729 if (port.length() && track->connect_input (track->input (x), port, this)) {
1735 if (!physoutputs.empty()) {
1736 uint32_t nphysical_out = physoutputs.size();
1738 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1741 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1742 port = physoutputs[(channels_used+x)%nphysical_out];
1743 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1744 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1745 port = _master_out->input (x % _master_out->n_inputs().n_audio())->name();
1749 if (port.length() && track->connect_output (track->output (x), port, this)) {
1755 channels_used += track->n_inputs ().n_audio();
1757 track->audio_diskstream()->non_realtime_input_change();
1759 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1760 track->set_remote_control_id (control_id);
1763 new_routes.push_back (track);
1764 ret.push_back (track);
1767 catch (failed_constructor &err) {
1768 error << _("Session: could not create new audio track.") << endmsg;
1771 /* we need to get rid of this, since the track failed to be created */
1772 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1775 RCUWriter<DiskstreamList> writer (diskstreams);
1776 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1777 ds->remove (track->audio_diskstream());
1784 catch (AudioEngine::PortRegistrationFailure& pfe) {
1786 error << pfe.what() << endmsg;
1789 /* we need to get rid of this, since the track failed to be created */
1790 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1793 RCUWriter<DiskstreamList> writer (diskstreams);
1794 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1795 ds->remove (track->audio_diskstream());
1806 if (!new_routes.empty()) {
1807 add_routes (new_routes, true);
1814 Session::set_remote_control_ids ()
1816 RemoteModel m = Config->get_remote_model();
1818 shared_ptr<RouteList> r = routes.reader ();
1820 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1821 if ( MixerOrdered == m) {
1822 long order = (*i)->order_key(N_("signal"));
1823 (*i)->set_remote_control_id( order+1 );
1824 } else if ( EditorOrdered == m) {
1825 long order = (*i)->order_key(N_("editor"));
1826 (*i)->set_remote_control_id( order+1 );
1827 } else if ( UserOrdered == m) {
1828 //do nothing ... only changes to remote id's are initiated by user
1835 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1838 uint32_t bus_id = 1;
1840 uint32_t channels_used = 0;
1843 uint32_t control_id;
1845 /* count existing audio busses */
1848 shared_ptr<RouteList> r = routes.reader ();
1850 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1851 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1853 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1856 channels_used += (*i)->n_inputs().n_audio();
1862 vector<string> physinputs;
1863 vector<string> physoutputs;
1865 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1866 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1868 n_physical_audio_outputs = physoutputs.size();
1869 n_physical_audio_inputs = physinputs.size();
1871 control_id = ntracks() + nbusses() + 1;
1876 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1880 if (route_by_name (bus_name) == 0) {
1884 } while (bus_id < (UINT_MAX-1));
1887 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1889 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1890 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1891 input_channels, output_channels)
1899 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1903 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1904 port = physinputs[((n+x)%n_physical_audio_inputs)];
1907 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1913 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1916 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1917 port = physoutputs[((n+x)%n_physical_outputs)];
1918 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1920 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1924 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1929 channels_used += bus->n_inputs ().n_audio();
1931 bus->set_remote_control_id (control_id);
1934 ret.push_back (bus);
1938 catch (failed_constructor &err) {
1939 error << _("Session: could not create new audio route.") << endmsg;
1943 catch (AudioEngine::PortRegistrationFailure& pfe) {
1944 error << pfe.what() << endmsg;
1954 add_routes (ret, true);
1962 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1966 uint32_t control_id;
1969 if (!tree.read (template_path.c_str())) {
1973 XMLNode* node = tree.root();
1975 control_id = ntracks() + nbusses() + 1;
1979 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1981 std::string node_name = IO::name_from_state (*node_copy.children().front());
1983 if (route_by_name (node_name) != 0) {
1985 /* generate a new name by adding a number to the end of the template name */
1987 uint32_t number = 1;
1990 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
1994 if (route_by_name (name) == 0) {
1998 } while (number < UINT_MAX);
2000 if (number == UINT_MAX) {
2001 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2005 IO::set_name_in_state (*node_copy.children().front(), name);
2008 Track::zero_diskstream_id_in_xml (node_copy);
2011 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2014 error << _("Session: cannot create track/bus from template description") << endmsg;
2018 if (boost::dynamic_pointer_cast<Track>(route)) {
2019 /* force input/output change signals so that the new diskstream
2020 picks up the configuration of the route. During session
2021 loading this normally happens in a different way.
2023 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2024 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2027 route->set_remote_control_id (control_id);
2030 ret.push_back (route);
2033 catch (failed_constructor &err) {
2034 error << _("Session: could not create new route from template") << endmsg;
2038 catch (AudioEngine::PortRegistrationFailure& pfe) {
2039 error << pfe.what() << endmsg;
2048 add_routes (ret, true);
2055 Session::add_routes (RouteList& new_routes, bool save)
2058 RCUWriter<RouteList> writer (routes);
2059 shared_ptr<RouteList> r = writer.get_copy ();
2060 r->insert (r->end(), new_routes.begin(), new_routes.end());
2061 resort_routes_using (r);
2064 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2066 boost::weak_ptr<Route> wpr (*x);
2068 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2069 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2070 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2071 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2073 if ((*x)->is_master()) {
2077 if ((*x)->is_control()) {
2078 _control_out = (*x);
2082 if (_control_out && IO::connecting_legal) {
2084 vector<string> cports;
2085 uint32_t ni = _control_out->n_inputs().n_audio();
2087 for (uint32_t n = 0; n < ni; ++n) {
2088 cports.push_back (_control_out->input(n)->name());
2091 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2092 (*x)->set_control_outs (cports);
2099 save_state (_current_snapshot_name);
2102 RouteAdded (new_routes); /* EMIT SIGNAL */
2106 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2108 /* need to do this in case we're rolling at the time, to prevent false underruns */
2109 dstream->do_refill_with_alloc ();
2111 dstream->set_block_size (current_block_size);
2114 RCUWriter<DiskstreamList> writer (diskstreams);
2115 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2116 ds->push_back (dstream);
2117 /* writer goes out of scope, copies ds back to main */
2120 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2121 /* this will connect to future changes, and check the current length */
2122 diskstream_playlist_changed (dstream);
2124 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2126 dstream->prepare ();
2131 Session::remove_route (shared_ptr<Route> route)
2134 RCUWriter<RouteList> writer (routes);
2135 shared_ptr<RouteList> rs = writer.get_copy ();
2139 /* deleting the master out seems like a dumb
2140 idea, but its more of a UI policy issue
2144 if (route == _master_out) {
2145 _master_out = shared_ptr<Route> ();
2148 if (route == _control_out) {
2149 _control_out = shared_ptr<Route> ();
2151 /* cancel control outs for all routes */
2153 vector<string> empty;
2155 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2156 (*r)->set_control_outs (empty);
2160 update_route_solo_state ();
2162 /* writer goes out of scope, forces route list update */
2165 boost::shared_ptr<Track> t;
2166 boost::shared_ptr<Diskstream> ds;
2168 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2169 ds = t->diskstream();
2175 RCUWriter<DiskstreamList> dsl (diskstreams);
2176 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2181 find_current_end ();
2183 // We need to disconnect the routes inputs and outputs
2185 route->disconnect_inputs (0);
2186 route->disconnect_outputs (0);
2188 update_latency_compensation (false, false);
2191 /* get rid of it from the dead wood collection in the route list manager */
2193 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2197 /* try to cause everyone to drop their references */
2199 route->drop_references ();
2201 sync_order_keys (N_("session"));
2203 /* save the new state of the world */
2205 if (save_state (_current_snapshot_name)) {
2206 save_history (_current_snapshot_name);
2211 Session::route_mute_changed (void* src)
2217 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2219 if (solo_update_disabled) {
2225 boost::shared_ptr<Route> route = wpr.lock ();
2228 /* should not happen */
2229 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2233 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2235 shared_ptr<RouteList> r = routes.reader ();
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2239 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2243 /* don't mess with busses */
2245 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
2251 /* don't mess with tracks */
2253 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
2258 if ((*i) != route &&
2259 ((*i)->mix_group () == 0 ||
2260 (*i)->mix_group () != route->mix_group () ||
2261 !route->mix_group ()->is_active())) {
2263 if ((*i)->soloed()) {
2265 /* if its already soloed, and solo latching is enabled,
2266 then leave it as it is.
2269 if (Config->get_solo_latched()) {
2276 solo_update_disabled = true;
2277 (*i)->set_solo (false, src);
2278 solo_update_disabled = false;
2282 bool something_soloed = false;
2283 bool same_thing_soloed = false;
2284 bool signal = false;
2286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2287 if ((*i)->soloed()) {
2288 something_soloed = true;
2289 if (boost::dynamic_pointer_cast<Track>(*i)) {
2291 same_thing_soloed = true;
2296 same_thing_soloed = true;
2304 if (something_soloed != currently_soloing) {
2306 currently_soloing = something_soloed;
2309 modify_solo_mute (is_track, same_thing_soloed);
2312 SoloActive (currently_soloing); /* EMIT SIGNAL */
2315 SoloChanged (); /* EMIT SIGNAL */
2321 Session::update_route_solo_state ()
2324 bool is_track = false;
2325 bool signal = false;
2327 /* this is where we actually implement solo by changing
2328 the solo mute setting of each track.
2331 shared_ptr<RouteList> r = routes.reader ();
2333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2334 if ((*i)->soloed()) {
2336 if (boost::dynamic_pointer_cast<Track>(*i)) {
2343 if (mute != currently_soloing) {
2345 currently_soloing = mute;
2348 if (!is_track && !mute) {
2350 /* nothing is soloed */
2352 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2353 (*i)->set_solo_mute (false);
2363 modify_solo_mute (is_track, mute);
2366 SoloActive (currently_soloing);
2371 Session::modify_solo_mute (bool is_track, bool mute)
2373 shared_ptr<RouteList> r = routes.reader ();
2375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 /* only alter track solo mute */
2381 if (boost::dynamic_pointer_cast<Track>(*i)) {
2382 if ((*i)->soloed()) {
2383 (*i)->set_solo_mute (!mute);
2385 (*i)->set_solo_mute (mute);
2391 /* only alter bus solo mute */
2393 if (!boost::dynamic_pointer_cast<Track>(*i)) {
2395 if ((*i)->soloed()) {
2397 (*i)->set_solo_mute (false);
2401 /* don't mute master or control outs
2402 in response to another bus solo
2405 if ((*i) != _master_out &&
2406 (*i) != _control_out) {
2407 (*i)->set_solo_mute (mute);
2418 Session::catch_up_on_solo ()
2420 /* this is called after set_state() to catch the full solo
2421 state, which can't be correctly determined on a per-route
2422 basis, but needs the global overview that only the session
2425 update_route_solo_state();
2429 Session::catch_up_on_solo_mute_override ()
2431 if (Config->get_solo_model() != InverseMute) {
2435 /* this is called whenever the param solo-mute-override is
2438 shared_ptr<RouteList> r = routes.reader ();
2440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2441 (*i)->catch_up_on_solo_mute_override ();
2446 Session::route_by_name (string name)
2448 shared_ptr<RouteList> r = routes.reader ();
2450 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2451 if ((*i)->name() == name) {
2456 return shared_ptr<Route> ((Route*) 0);
2460 Session::route_by_id (PBD::ID id)
2462 shared_ptr<RouteList> r = routes.reader ();
2464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2465 if ((*i)->id() == id) {
2470 return shared_ptr<Route> ((Route*) 0);
2474 Session::route_by_remote_id (uint32_t id)
2476 shared_ptr<RouteList> r = routes.reader ();
2478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2479 if ((*i)->remote_control_id() == id) {
2484 return shared_ptr<Route> ((Route*) 0);
2488 Session::find_current_end ()
2490 if (_state_of_the_state & Loading) {
2494 nframes_t max = get_maximum_extent ();
2496 if (max > end_location->end()) {
2497 end_location->set_end (max);
2499 DurationChanged(); /* EMIT SIGNAL */
2504 Session::get_maximum_extent () const
2509 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2511 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2512 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2514 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2515 if ((me = pl->get_maximum_extent()) > max) {
2523 boost::shared_ptr<Diskstream>
2524 Session::diskstream_by_name (string name)
2526 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2528 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2529 if ((*i)->name() == name) {
2534 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2537 boost::shared_ptr<Diskstream>
2538 Session::diskstream_by_id (const PBD::ID& id)
2540 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2542 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2543 if ((*i)->id() == id) {
2548 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2551 /* Region management */
2554 Session::new_region_name (string old)
2556 string::size_type last_period;
2558 string::size_type len = old.length() + 64;
2561 if ((last_period = old.find_last_of ('.')) == string::npos) {
2563 /* no period present - add one explicitly */
2566 last_period = old.length() - 1;
2571 number = atoi (old.substr (last_period+1).c_str());
2575 while (number < (UINT_MAX-1)) {
2577 RegionList::const_iterator i;
2582 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2585 for (i = regions.begin(); i != regions.end(); ++i) {
2586 if (i->second->name() == sbuf) {
2591 if (i == regions.end()) {
2596 if (number != (UINT_MAX-1)) {
2600 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2605 Session::region_name (string& result, string base, bool newlevel)
2610 if (base.find("/") != string::npos) {
2611 base = base.substr(base.find_last_of("/") + 1);
2616 Glib::Mutex::Lock lm (region_lock);
2618 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2627 string::size_type pos;
2629 pos = base.find_last_of ('.');
2631 /* pos may be npos, but then we just use entire base */
2633 subbase = base.substr (0, pos);
2638 Glib::Mutex::Lock lm (region_lock);
2640 map<string,uint32_t>::iterator x;
2644 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2646 region_name_map[subbase] = 1;
2649 snprintf (buf, sizeof (buf), ".%d", x->second);
2660 Session::add_region (boost::shared_ptr<Region> region)
2662 vector<boost::shared_ptr<Region> > v;
2663 v.push_back (region);
2668 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2673 Glib::Mutex::Lock lm (region_lock);
2675 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2677 boost::shared_ptr<Region> region = *ii;
2681 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2685 RegionList::iterator x;
2687 for (x = regions.begin(); x != regions.end(); ++x) {
2689 if (region->region_list_equivalent (x->second)) {
2694 if (x == regions.end()) {
2696 pair<RegionList::key_type,RegionList::mapped_type> entry;
2698 entry.first = region->id();
2699 entry.second = region;
2701 pair<RegionList::iterator,bool> x = regions.insert (entry);
2713 /* mark dirty because something has changed even if we didn't
2714 add the region to the region list.
2721 vector<boost::weak_ptr<Region> > v;
2722 boost::shared_ptr<Region> first_r;
2724 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2726 boost::shared_ptr<Region> region = *ii;
2730 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2733 v.push_back (region);
2740 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2741 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2743 update_region_name_map (region);
2747 RegionsAdded (v); /* EMIT SIGNAL */
2753 Session::update_region_name_map (boost::shared_ptr<Region> region)
2755 string::size_type last_period = region->name().find_last_of ('.');
2757 if (last_period != string::npos && last_period < region->name().length() - 1) {
2759 string base = region->name().substr (0, last_period);
2760 string number = region->name().substr (last_period+1);
2761 map<string,uint32_t>::iterator x;
2763 /* note that if there is no number, we get zero from atoi,
2767 region_name_map[base] = atoi (number);
2772 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2774 boost::shared_ptr<Region> region (weak_region.lock ());
2780 if (what_changed & Region::HiddenChanged) {
2781 /* relay hidden changes */
2782 RegionHiddenChange (region);
2785 if (what_changed & NameChanged) {
2786 update_region_name_map (region);
2791 Session::remove_region (boost::weak_ptr<Region> weak_region)
2793 RegionList::iterator i;
2794 boost::shared_ptr<Region> region (weak_region.lock ());
2800 bool removed = false;
2803 Glib::Mutex::Lock lm (region_lock);
2805 if ((i = regions.find (region->id())) != regions.end()) {
2811 /* mark dirty because something has changed even if we didn't
2812 remove the region from the region list.
2818 RegionRemoved(region); /* EMIT SIGNAL */
2822 boost::shared_ptr<Region>
2823 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2825 RegionList::iterator i;
2826 boost::shared_ptr<Region> region;
2828 Glib::Mutex::Lock lm (region_lock);
2830 for (i = regions.begin(); i != regions.end(); ++i) {
2834 if (region->whole_file()) {
2836 if (child->source_equivalent (region)) {
2842 return boost::shared_ptr<Region> ();
2846 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2848 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2849 (*i)->get_region_list_equivalent_regions (region, result);
2853 Session::destroy_region (boost::shared_ptr<Region> region)
2855 vector<boost::shared_ptr<Source> > srcs;
2858 if (region->playlist()) {
2859 region->playlist()->destroy_region (region);
2862 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2863 srcs.push_back (region->source (n));
2867 region->drop_references ();
2869 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2871 (*i)->mark_for_remove ();
2872 (*i)->drop_references ();
2874 cerr << "source was not used by any playlist\n";
2881 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2883 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2884 destroy_region (*i);
2890 Session::remove_last_capture ()
2892 list<boost::shared_ptr<Region> > r;
2894 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2896 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2897 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2900 r.insert (r.end(), l.begin(), l.end());
2905 destroy_regions (r);
2907 save_state (_current_snapshot_name);
2913 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2919 /* Source Management */
2922 Session::add_source (boost::shared_ptr<Source> source)
2924 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2925 pair<SourceMap::iterator,bool> result;
2927 entry.first = source->id();
2928 entry.second = source;
2931 Glib::Mutex::Lock lm (source_lock);
2932 result = sources.insert (entry);
2935 if (result.second) {
2936 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2940 boost::shared_ptr<AudioFileSource> afs;
2942 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2943 if (Config->get_auto_analyse_audio()) {
2944 Analyser::queue_source_for_analysis (source, false);
2950 Session::remove_source (boost::weak_ptr<Source> src)
2952 SourceMap::iterator i;
2953 boost::shared_ptr<Source> source = src.lock();
2960 Glib::Mutex::Lock lm (source_lock);
2962 if ((i = sources.find (source->id())) != sources.end()) {
2967 if (!_state_of_the_state & InCleanup) {
2969 /* save state so we don't end up with a session file
2970 referring to non-existent sources.
2973 save_state (_current_snapshot_name);
2977 boost::shared_ptr<Source>
2978 Session::source_by_id (const PBD::ID& id)
2980 Glib::Mutex::Lock lm (source_lock);
2981 SourceMap::iterator i;
2982 boost::shared_ptr<Source> source;
2984 if ((i = sources.find (id)) != sources.end()) {
2991 boost::shared_ptr<Source>
2992 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2994 Glib::Mutex::Lock lm (source_lock);
2996 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2997 cerr << "comparing " << path << " with " << i->second->name() << endl;
2998 boost::shared_ptr<AudioFileSource> afs
2999 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3001 if (afs && afs->path() == path && chn == afs->channel()) {
3005 return boost::shared_ptr<Source>();
3010 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3013 string old_basename = PBD::basename_nosuffix (oldname);
3014 string new_legalized = legalize_for_path (newname);
3016 /* note: we know (or assume) the old path is already valid */
3020 /* destructive file sources have a name of the form:
3022 /path/to/Tnnnn-NAME(%[LR])?.wav
3024 the task here is to replace NAME with the new name.
3027 /* find last slash */
3031 string::size_type slash;
3032 string::size_type dash;
3034 if ((slash = path.find_last_of ('/')) == string::npos) {
3038 dir = path.substr (0, slash+1);
3040 /* '-' is not a legal character for the NAME part of the path */
3042 if ((dash = path.find_last_of ('-')) == string::npos) {
3046 prefix = path.substr (slash+1, dash-(slash+1));
3051 path += new_legalized;
3052 path += ".wav"; /* XXX gag me with a spoon */
3056 /* non-destructive file sources have a name of the form:
3058 /path/to/NAME-nnnnn(%[LR])?.ext
3060 the task here is to replace NAME with the new name.
3065 string::size_type slash;
3066 string::size_type dash;
3067 string::size_type postfix;
3069 /* find last slash */
3071 if ((slash = path.find_last_of ('/')) == string::npos) {
3075 dir = path.substr (0, slash+1);
3077 /* '-' is not a legal character for the NAME part of the path */
3079 if ((dash = path.find_last_of ('-')) == string::npos) {
3083 suffix = path.substr (dash+1);
3085 // Suffix is now everything after the dash. Now we need to eliminate
3086 // the nnnnn part, which is done by either finding a '%' or a '.'
3088 postfix = suffix.find_last_of ("%");
3089 if (postfix == string::npos) {
3090 postfix = suffix.find_last_of ('.');
3093 if (postfix != string::npos) {
3094 suffix = suffix.substr (postfix);
3096 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3100 const uint32_t limit = 10000;
3101 char buf[PATH_MAX+1];
3103 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3105 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3107 if (access (buf, F_OK) != 0) {
3115 error << "FATAL ERROR! Could not find a " << endl;
3123 /** Return the full path (in some session directory) for a new embedded source.
3124 * \a name must be a session-unique name that does not contain slashes
3125 * (e.g. as returned by new_*_source_name)
3128 Session::new_source_path_from_name (DataType type, const string& name)
3130 assert(name.find("/") == string::npos);
3132 SessionDirectory sdir(get_best_session_directory_for_new_source());
3135 if (type == DataType::AUDIO) {
3136 p = sdir.sound_path();
3137 } else if (type == DataType::MIDI) {
3138 p = sdir.midi_path();
3140 error << "Unknown source type, unable to create file path" << endmsg;
3145 return p.to_string();
3149 Session::peak_path (Glib::ustring base) const
3151 sys::path peakfile_path(_session_dir->peak_path());
3152 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3153 return peakfile_path.to_string();
3156 /** Return a unique name based on \a base for a new internal audio source */
3158 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3162 char buf[PATH_MAX+1];
3163 const uint32_t limit = 10000;
3167 legalized = legalize_for_path (base);
3169 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3170 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3172 vector<space_and_path>::iterator i;
3173 uint32_t existing = 0;
3175 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3177 SessionDirectory sdir((*i).path);
3179 spath = sdir.sound_path().to_string();
3184 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3185 spath.c_str(), cnt, legalized.c_str());
3186 } else if (nchan == 2) {
3188 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3189 spath.c_str(), cnt, legalized.c_str());
3191 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3192 spath.c_str(), cnt, legalized.c_str());
3194 } else if (nchan < 26) {
3195 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3196 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3198 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3199 spath.c_str(), cnt, legalized.c_str());
3208 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3209 } else if (nchan == 2) {
3211 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3213 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3215 } else if (nchan < 26) {
3216 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3218 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3222 if (sys::exists(buf)) {
3228 if (existing == 0) {
3233 error << string_compose(
3234 _("There are already %1 recordings for %2, which I consider too many."),
3235 limit, base) << endmsg;
3237 throw failed_constructor();
3241 return Glib::path_get_basename(buf);
3244 /** Create a new embedded audio source */
3245 boost::shared_ptr<AudioFileSource>
3246 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3248 const size_t n_chans = ds.n_channels().n_audio();
3249 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3250 const string path = new_source_path_from_name(DataType::AUDIO, name);
3251 return boost::dynamic_pointer_cast<AudioFileSource> (
3252 SourceFactory::createWritable (
3253 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3256 /** Return a unique name based on \a base for a new internal MIDI source */
3258 Session::new_midi_source_name (const string& base)
3261 char buf[PATH_MAX+1];
3262 const uint32_t limit = 10000;
3266 legalized = legalize_for_path (base);
3268 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3269 for (cnt = 1; cnt <= limit; ++cnt) {
3271 vector<space_and_path>::iterator i;
3272 uint32_t existing = 0;
3274 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3276 SessionDirectory sdir((*i).path);
3278 sys::path p = sdir.midi_path();
3281 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3283 if (sys::exists (buf)) {
3288 if (existing == 0) {
3293 error << string_compose(
3294 _("There are already %1 recordings for %2, which I consider too many."),
3295 limit, base) << endmsg;
3297 throw failed_constructor();
3301 return Glib::path_get_basename(buf);
3305 /** Create a new embedded MIDI source */
3306 boost::shared_ptr<MidiSource>
3307 Session::create_midi_source_for_session (MidiDiskstream& ds)
3309 const string name = new_midi_source_name (ds.name());
3310 const string path = new_source_path_from_name (DataType::MIDI, name);
3312 return boost::dynamic_pointer_cast<SMFSource> (
3313 SourceFactory::createWritable (
3314 DataType::MIDI, *this, path, true, false, frame_rate()));
3318 /* Playlist management */
3320 boost::shared_ptr<Playlist>
3321 Session::playlist_by_name (string name)
3323 Glib::Mutex::Lock lm (playlist_lock);
3324 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3325 if ((*i)->name() == name) {
3329 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3330 if ((*i)->name() == name) {
3335 return boost::shared_ptr<Playlist>();
3339 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3341 Glib::Mutex::Lock lm (playlist_lock);
3342 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3343 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3344 list.push_back (*i);
3347 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3348 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3349 list.push_back (*i);
3355 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3357 if (playlist->hidden()) {
3362 Glib::Mutex::Lock lm (playlist_lock);
3363 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3364 playlists.insert (playlists.begin(), playlist);
3365 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3366 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3371 playlist->release();
3376 PlaylistAdded (playlist); /* EMIT SIGNAL */
3380 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3383 Glib::Mutex::Lock lm (playlist_lock);
3384 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3387 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3394 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3396 boost::shared_ptr<Playlist> pl(wpl.lock());
3402 PlaylistList::iterator x;
3405 /* its not supposed to be visible */
3410 Glib::Mutex::Lock lm (playlist_lock);
3414 unused_playlists.insert (pl);
3416 if ((x = playlists.find (pl)) != playlists.end()) {
3417 playlists.erase (x);
3423 playlists.insert (pl);
3425 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3426 unused_playlists.erase (x);
3433 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3435 if (_state_of_the_state & Deletion) {
3439 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3446 Glib::Mutex::Lock lm (playlist_lock);
3448 PlaylistList::iterator i;
3450 i = find (playlists.begin(), playlists.end(), playlist);
3451 if (i != playlists.end()) {
3452 playlists.erase (i);
3455 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3456 if (i != unused_playlists.end()) {
3457 unused_playlists.erase (i);
3464 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3468 Session::set_audition (boost::shared_ptr<Region> r)
3470 pending_audition_region = r;
3471 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3472 schedule_butler_transport_work ();
3476 Session::audition_playlist ()
3478 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3479 ev->region.reset ();
3484 Session::non_realtime_set_audition ()
3486 if (!pending_audition_region) {
3487 auditioner->audition_current_playlist ();
3489 auditioner->audition_region (pending_audition_region);
3490 pending_audition_region.reset ();
3492 AuditionActive (true); /* EMIT SIGNAL */
3496 Session::audition_region (boost::shared_ptr<Region> r)
3498 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3504 Session::cancel_audition ()
3506 if (auditioner->active()) {
3507 auditioner->cancel_audition ();
3508 AuditionActive (false); /* EMIT SIGNAL */
3513 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3515 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3519 Session::remove_empty_sounds ()
3521 vector<string> audio_filenames;
3523 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3525 Glib::Mutex::Lock lm (source_lock);
3527 TapeFileMatcher tape_file_matcher;
3529 remove_if (audio_filenames.begin(), audio_filenames.end(),
3530 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3532 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3534 sys::path audio_file_path (_session_dir->sound_path());
3536 audio_file_path /= *i;
3538 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3542 sys::remove (audio_file_path);
3543 const string peakfile = peak_path (audio_file_path.to_string());
3544 sys::remove (peakfile);
3546 catch (const sys::filesystem_error& err)
3548 error << err.what() << endmsg;
3555 Session::is_auditioning () const
3557 /* can be called before we have an auditioner object */
3559 return auditioner->active();
3566 Session::set_all_solo (bool yn)
3568 shared_ptr<RouteList> r = routes.reader ();
3570 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3571 if (!(*i)->is_hidden()) {
3572 (*i)->set_solo (yn, this);
3580 Session::set_all_mute (bool yn)
3582 shared_ptr<RouteList> r = routes.reader ();
3584 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3585 if (!(*i)->is_hidden()) {
3586 (*i)->set_mute (yn, this);
3594 Session::n_diskstreams () const
3598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3600 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3601 if (!(*i)->hidden()) {
3609 Session::graph_reordered ()
3611 /* don't do this stuff if we are setting up connections
3612 from a set_state() call or creating new tracks.
3615 if (_state_of_the_state & InitialConnecting) {
3619 /* every track/bus asked for this to be handled but it was deferred because
3620 we were connecting. do it now.
3623 request_input_change_handling ();
3627 /* force all diskstreams to update their capture offset values to
3628 reflect any changes in latencies within the graph.
3631 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3633 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3634 (*i)->set_capture_offset ();
3639 Session::record_disenable_all ()
3641 record_enable_change_all (false);
3645 Session::record_enable_all ()
3647 record_enable_change_all (true);
3651 Session::record_enable_change_all (bool yn)
3653 shared_ptr<RouteList> r = routes.reader ();
3655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3656 boost::shared_ptr<Track> t;
3658 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3659 t->set_record_enable (yn, this);
3663 /* since we don't keep rec-enable state, don't mark session dirty */
3667 Session::add_processor (Processor* processor)
3671 PortInsert* port_insert;
3672 PluginInsert* plugin_insert;
3674 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3675 _port_inserts.insert (_port_inserts.begin(), port_insert);
3676 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3677 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3678 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3679 _sends.insert (_sends.begin(), send);
3680 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3681 _returns.insert (_returns.begin(), retrn);
3683 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3687 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3693 Session::remove_processor (Processor* processor)
3697 PortInsert* port_insert;
3698 PluginInsert* plugin_insert;
3700 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3701 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3702 if (x != _port_inserts.end()) {
3703 insert_bitset[port_insert->bit_slot()] = false;
3704 _port_inserts.erase (x);
3706 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3707 _plugin_inserts.remove (plugin_insert);
3708 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3709 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3710 if (x != _sends.end()) {
3711 send_bitset[send->bit_slot()] = false;
3714 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3715 list<Return*>::iterator x = find (_returns.begin(), _returns.end(), retrn);
3716 if (x != _returns.end()) {
3717 return_bitset[send->bit_slot()] = false;
3721 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3729 Session::available_capture_duration ()
3731 float sample_bytes_on_disk = 4.0; // keep gcc happy
3733 switch (Config->get_native_file_data_format()) {
3735 sample_bytes_on_disk = 4.0;
3739 sample_bytes_on_disk = 3.0;
3743 sample_bytes_on_disk = 2.0;
3747 /* impossible, but keep some gcc versions happy */
3748 fatal << string_compose (_("programming error: %1"),
3749 X_("illegal native file data format"))
3754 double scale = 4096.0 / sample_bytes_on_disk;
3756 if (_total_free_4k_blocks * scale > (double) max_frames) {
3760 return (nframes_t) floor (_total_free_4k_blocks * scale);
3764 Session::add_bundle (shared_ptr<Bundle> bundle)
3767 RCUWriter<BundleList> writer (_bundles);
3768 boost::shared_ptr<BundleList> b = writer.get_copy ();
3769 b->push_back (bundle);
3772 BundleAdded (bundle); /* EMIT SIGNAL */
3778 Session::remove_bundle (shared_ptr<Bundle> bundle)
3780 bool removed = false;
3783 RCUWriter<BundleList> writer (_bundles);
3784 boost::shared_ptr<BundleList> b = writer.get_copy ();
3785 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3787 if (i != b->end()) {
3794 BundleRemoved (bundle); /* EMIT SIGNAL */
3801 Session::bundle_by_name (string name) const
3803 boost::shared_ptr<BundleList> b = _bundles.reader ();
3805 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3806 if ((*i)->name() == name) {
3811 return boost::shared_ptr<Bundle> ();
3815 Session::tempo_map_changed (Change ignored)
3819 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3820 (*i)->update_after_tempo_map_change ();
3823 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3824 (*i)->update_after_tempo_map_change ();
3830 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3831 * the given count with the current block size.
3834 Session::ensure_buffers (ChanCount howmany)
3836 if (current_block_size == 0) {
3837 return; // too early? (is this ok?)
3840 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3841 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3842 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3843 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3844 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3847 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3851 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3853 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3854 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3859 Session::next_insert_id ()
3861 /* this doesn't really loop forever. just think about it */
3864 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3865 if (!insert_bitset[n]) {
3866 insert_bitset[n] = true;
3872 /* none available, so resize and try again */
3874 insert_bitset.resize (insert_bitset.size() + 16, false);
3879 Session::next_send_id ()
3881 /* this doesn't really loop forever. just think about it */
3884 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3885 if (!send_bitset[n]) {
3886 send_bitset[n] = true;
3892 /* none available, so resize and try again */
3894 send_bitset.resize (send_bitset.size() + 16, false);
3899 Session::next_return_id ()
3901 /* this doesn't really loop forever. just think about it */
3904 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3905 if (!return_bitset[n]) {
3906 return_bitset[n] = true;
3912 /* none available, so resize and try again */
3914 return_bitset.resize (return_bitset.size() + 16, false);
3919 Session::mark_send_id (uint32_t id)
3921 if (id >= send_bitset.size()) {
3922 send_bitset.resize (id+16, false);
3924 if (send_bitset[id]) {
3925 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3927 send_bitset[id] = true;
3931 Session::mark_return_id (uint32_t id)
3933 if (id >= return_bitset.size()) {
3934 return_bitset.resize (id+16, false);
3936 if (return_bitset[id]) {
3937 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3939 return_bitset[id] = true;
3943 Session::mark_insert_id (uint32_t id)
3945 if (id >= insert_bitset.size()) {
3946 insert_bitset.resize (id+16, false);
3948 if (insert_bitset[id]) {
3949 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3951 insert_bitset[id] = true;
3954 /* Named Selection management */
3957 Session::named_selection_by_name (string name)
3959 Glib::Mutex::Lock lm (named_selection_lock);
3960 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3961 if ((*i)->name == name) {
3969 Session::add_named_selection (NamedSelection* named_selection)
3972 Glib::Mutex::Lock lm (named_selection_lock);
3973 named_selections.insert (named_selections.begin(), named_selection);
3976 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3982 NamedSelectionAdded (); /* EMIT SIGNAL */
3986 Session::remove_named_selection (NamedSelection* named_selection)
3988 bool removed = false;
3991 Glib::Mutex::Lock lm (named_selection_lock);
3993 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3995 if (i != named_selections.end()) {
3997 named_selections.erase (i);
4004 NamedSelectionRemoved (); /* EMIT SIGNAL */
4009 Session::reset_native_file_format ()
4011 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4013 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4014 (*i)->reset_write_sources (false);
4019 Session::route_name_unique (string n) const
4021 shared_ptr<RouteList> r = routes.reader ();
4023 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4024 if ((*i)->name() == n) {
4033 Session::route_name_internal (string n) const
4035 if (auditioner && auditioner->name() == n) {
4039 if (_click_io && _click_io->name() == n) {
4047 Session::n_playlists () const
4049 Glib::Mutex::Lock lm (playlist_lock);
4050 return playlists.size();
4054 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4056 if (!force && howmany <= _npan_buffers) {
4060 if (_pan_automation_buffer) {
4062 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4063 delete [] _pan_automation_buffer[i];
4066 delete [] _pan_automation_buffer;
4069 _pan_automation_buffer = new pan_t*[howmany];
4071 for (uint32_t i = 0; i < howmany; ++i) {
4072 _pan_automation_buffer[i] = new pan_t[nframes];
4075 _npan_buffers = howmany;
4079 Session::freeze (InterThreadInfo& itt)
4081 shared_ptr<RouteList> r = routes.reader ();
4083 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4085 boost::shared_ptr<Track> t;
4087 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4088 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4098 boost::shared_ptr<Region>
4099 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4100 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4101 InterThreadInfo& itt, bool enable_processing)
4103 boost::shared_ptr<Region> result;
4104 boost::shared_ptr<Playlist> playlist;
4105 boost::shared_ptr<AudioFileSource> fsource;
4107 char buf[PATH_MAX+1];
4108 ChanCount nchans(track.audio_diskstream()->n_channels());
4110 nframes_t this_chunk;
4113 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4114 const string sound_dir = sdir.sound_path().to_string();
4115 nframes_t len = end - start;
4118 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4119 end, start) << endmsg;
4123 // any bigger than this seems to cause stack overflows in called functions
4124 const nframes_t chunk_size = (128 * 1024)/4;
4126 // block all process callback handling
4128 block_processing ();
4130 /* call tree *MUST* hold route_lock */
4132 if ((playlist = track.diskstream()->playlist()) == 0) {
4136 /* external redirects will be a problem */
4138 if (track.has_external_redirects()) {
4142 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4144 for (x = 0; x < 99999; ++x) {
4145 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4146 if (access (buf, F_OK) != 0) {
4152 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4157 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4158 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4161 catch (failed_constructor& err) {
4162 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4166 srcs.push_back (fsource);
4169 /* XXX need to flush all redirects */
4174 /* create a set of reasonably-sized buffers */
4175 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4176 buffers.set_count(nchans);
4178 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4179 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4181 afs->prepare_for_peakfile_writes ();
4184 while (to_do && !itt.cancel) {
4186 this_chunk = min (to_do, chunk_size);
4188 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4193 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4194 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4197 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4203 start += this_chunk;
4204 to_do -= this_chunk;
4206 itt.progress = (float) (1.0 - ((double) to_do / len));
4215 xnow = localtime (&now);
4217 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4218 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4221 afs->update_header (position, *xnow, now);
4222 afs->flush_header ();
4226 /* construct a region to represent the bounced material */
4228 result = RegionFactory::create (srcs, 0,
4229 srcs.front()->length(srcs.front()->timeline_position()),
4230 region_name_from_path (srcs.front()->name(), true));
4235 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4236 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4239 afs->mark_for_remove ();
4242 (*src)->drop_references ();
4246 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4247 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4250 afs->done_with_peakfile_writes ();
4254 unblock_processing ();
4260 Session::get_silent_buffers (ChanCount count)
4262 assert(_silent_buffers->available() >= count);
4263 _silent_buffers->set_count(count);
4265 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4266 for (size_t i= 0; i < count.get(*t); ++i) {
4267 _silent_buffers->get(*t, i).clear();
4271 return *_silent_buffers;
4275 Session::get_scratch_buffers (ChanCount count)
4277 if (count != ChanCount::ZERO) {
4278 assert(_scratch_buffers->available() >= count);
4279 _scratch_buffers->set_count(count);
4281 _scratch_buffers->set_count (_scratch_buffers->available());
4284 return *_scratch_buffers;
4288 Session::get_mix_buffers (ChanCount count)
4290 assert(_mix_buffers->available() >= count);
4291 _mix_buffers->set_count(count);
4292 return *_mix_buffers;
4296 Session::ntracks () const
4299 shared_ptr<RouteList> r = routes.reader ();
4301 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4302 if (boost::dynamic_pointer_cast<Track> (*i)) {
4311 Session::nbusses () const
4314 shared_ptr<RouteList> r = routes.reader ();
4316 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4317 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4326 Session::add_automation_list(AutomationList *al)
4328 automation_lists[al->id()] = al;
4332 Session::compute_initial_length ()
4334 return _engine.frame_rate() * 60 * 5;
4338 Session::sync_order_keys (const char* base)
4340 if (!Config->get_sync_all_route_ordering()) {
4341 /* leave order keys as they are */
4345 boost::shared_ptr<RouteList> r = routes.reader ();
4347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4348 (*i)->sync_order_keys (base);
4351 Route::SyncOrderKeys (base); // EMIT SIGNAL
4355 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4357 Session::have_rec_enabled_diskstream () const
4359 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4362 /** Update the state of our rec-enabled diskstreams flag */
4364 Session::update_have_rec_enabled_diskstream ()
4366 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4367 DiskstreamList::iterator i = dsl->begin ();
4368 while (i != dsl->end () && (*i)->record_enabled () == false) {
4372 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4374 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4376 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4377 RecordStateChanged (); /* EMIT SIGNAL */