2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_port.h"
50 #include "ardour/audio_track.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/audiofilesource.h"
53 #include "ardour/audioplaylist.h"
54 #include "ardour/audioregion.h"
55 #include "ardour/auditioner.h"
56 #include "ardour/buffer_set.h"
57 #include "ardour/bundle.h"
58 #include "ardour/click.h"
59 #include "ardour/configuration.h"
60 #include "ardour/crossfade.h"
61 #include "ardour/cycle_timer.h"
62 #include "ardour/data_type.h"
63 #include "ardour/filename_extensions.h"
64 #include "ardour/io_processor.h"
65 #include "ardour/midi_diskstream.h"
66 #include "ardour/midi_playlist.h"
67 #include "ardour/midi_region.h"
68 #include "ardour/midi_track.h"
69 #include "ardour/named_selection.h"
70 #include "ardour/playlist.h"
71 #include "ardour/plugin_insert.h"
72 #include "ardour/port_insert.h"
73 #include "ardour/processor.h"
74 #include "ardour/recent_sessions.h"
75 #include "ardour/region_factory.h"
76 #include "ardour/return.h"
77 #include "ardour/route_group.h"
78 #include "ardour/send.h"
79 #include "ardour/session.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_directory.h"
82 #include "ardour/session_metadata.h"
83 #include "ardour/slave.h"
84 #include "ardour/smf_source.h"
85 #include "ardour/source_factory.h"
86 #include "ardour/tape_file_matcher.h"
87 #include "ardour/tempo.h"
88 #include "ardour/utils.h"
93 using namespace ARDOUR;
95 using boost::shared_ptr;
97 bool Session::_disable_all_loaded_plugins = false;
99 sigc::signal<void,std::string> Session::Dialog;
100 sigc::signal<int> Session::AskAboutPendingState;
101 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
102 sigc::signal<void> Session::SendFeedback;
104 sigc::signal<void> Session::SMPTEOffsetChanged;
105 sigc::signal<void> Session::StartTimeChanged;
106 sigc::signal<void> Session::EndTimeChanged;
107 sigc::signal<void> Session::AutoBindingOn;
108 sigc::signal<void> Session::AutoBindingOff;
109 sigc::signal<void, std::string, std::string> Session::Exported;
111 Session::Session (AudioEngine &eng,
112 const string& fullpath,
113 const string& snapshot_name,
117 _target_transport_speed (0.0),
118 _requested_return_frame (-1),
119 _scratch_buffers(new BufferSet()),
120 _silent_buffers(new BufferSet()),
121 _mix_buffers(new BufferSet()),
123 _mmc_port (default_mmc_port),
124 _mtc_port (default_mtc_port),
125 _midi_port (default_midi_port),
126 _midi_clock_port (default_midi_clock_port),
127 _session_dir (new SessionDirectory(fullpath)),
128 pending_events (2048),
130 butler_mixdown_buffer (0),
131 butler_gain_buffer (0),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
134 midi_thread (pthread_t (0)),
135 midi_requests (128), // the size of this should match the midi request pool size
136 diskstreams (new DiskstreamList),
137 routes (new RouteList),
138 _total_free_4k_blocks (0),
139 _bundles (new BundleList),
140 _bundle_xml_node (0),
143 click_emphasis_data (0),
145 _metadata (new SessionMetadata()),
146 _have_rec_enabled_diskstream (false)
151 interpolation.add_channel_to (0, 0);
153 if (!eng.connected()) {
154 throw failed_constructor();
157 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
159 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
160 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
162 first_stage_init (fullpath, snapshot_name);
164 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
167 if (create (new_session, mix_template, compute_initial_length())) {
169 throw failed_constructor ();
173 if (second_stage_init (new_session)) {
175 throw failed_constructor ();
178 store_recent_sessions(_name, _path);
180 bool was_dirty = dirty();
182 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
184 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
185 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _target_transport_speed (0.0),
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 butler_mixdown_buffer (0),
218 butler_gain_buffer (0),
219 post_transport_work((PostTransportWork)0),
220 _send_smpte_update (false),
221 midi_thread (pthread_t (0)),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
225 _total_free_4k_blocks (0),
226 _bundles (new BundleList),
227 _bundle_xml_node (0),
228 _click_io ((IO *) 0),
230 click_emphasis_data (0),
232 _metadata (new SessionMetadata()),
233 _have_rec_enabled_diskstream (false)
237 interpolation.add_channel_to (0, 0);
239 if (!eng.connected()) {
240 throw failed_constructor();
243 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
245 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
246 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
248 if (n_physical_inputs) {
249 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
252 if (n_physical_outputs) {
253 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
256 first_stage_init (fullpath, snapshot_name);
258 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
261 if (create (new_session, string(), initial_length)) {
263 throw failed_constructor ();
268 /* set up Master Out and Control Out if necessary */
273 if (master_out_channels) {
274 ChanCount count(DataType::AUDIO, master_out_channels);
275 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
276 r->input()->ensure_io (count, false, this);
277 r->output()->ensure_io (count, false, this);
278 r->set_remote_control_id (control_id);
282 /* prohibit auto-connect to master, because there isn't one */
283 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
286 if (control_out_channels) {
287 ChanCount count(DataType::AUDIO, control_out_channels);
288 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
289 r->input()->ensure_io (count, false, this);
290 r->output()->ensure_io (count, false, this);
291 r->set_remote_control_id (control_id++);
297 add_routes (rl, false);
302 if (no_auto_connect()) {
303 input_ac = AutoConnectOption (0);
304 output_ac = AutoConnectOption (0);
307 Config->set_input_auto_connect (input_ac);
308 Config->set_output_auto_connect (output_ac);
310 if (second_stage_init (new_session)) {
312 throw failed_constructor ();
315 store_recent_sessions (_name, _path);
317 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
319 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
330 /* if we got to here, leaving pending capture state around
334 remove_pending_capture_state ();
336 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
338 _engine.remove_session ();
340 GoingAway (); /* EMIT SIGNAL */
346 /* clear history so that no references to objects are held any more */
350 /* clear state tree so that no references to objects are held any more */
354 terminate_butler_thread ();
355 //terminate_midi_thread ();
357 if (click_data != default_click) {
358 delete [] click_data;
361 if (click_emphasis_data != default_click_emphasis) {
362 delete [] click_emphasis_data;
367 delete _scratch_buffers;
368 delete _silent_buffers;
371 AudioDiskstream::free_working_buffers();
373 Route::SyncOrderKeys.clear();
375 #undef TRACK_DESTRUCTION
376 #ifdef TRACK_DESTRUCTION
377 cerr << "delete named selections\n";
378 #endif /* TRACK_DESTRUCTION */
379 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
380 NamedSelectionList::iterator tmp;
389 #ifdef TRACK_DESTRUCTION
390 cerr << "delete playlists\n";
391 #endif /* TRACK_DESTRUCTION */
392 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
393 PlaylistList::iterator tmp;
398 (*i)->drop_references ();
403 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
404 PlaylistList::iterator tmp;
409 (*i)->drop_references ();
415 unused_playlists.clear ();
417 #ifdef TRACK_DESTRUCTION
418 cerr << "delete regions\n";
419 #endif /* TRACK_DESTRUCTION */
421 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
422 RegionList::iterator tmp;
427 i->second->drop_references ();
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete routes\n";
436 #endif /* TRACK_DESTRUCTION */
438 RCUWriter<RouteList> writer (routes);
439 boost::shared_ptr<RouteList> r = writer.get_copy ();
440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
441 (*i)->drop_references ();
444 /* writer goes out of scope and updates master */
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete diskstreams\n";
451 #endif /* TRACK_DESTRUCTION */
453 RCUWriter<DiskstreamList> dwriter (diskstreams);
454 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
455 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
456 (*i)->drop_references ();
460 diskstreams.flush ();
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete audio sources\n";
464 #endif /* TRACK_DESTRUCTION */
465 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
466 SourceMap::iterator tmp;
471 i->second->drop_references ();
478 #ifdef TRACK_DESTRUCTION
479 cerr << "delete route groups\n";
480 #endif /* TRACK_DESTRUCTION */
481 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ) {
485 delete [] butler_mixdown_buffer;
486 delete [] butler_gain_buffer;
488 Crossfade::set_buffer_size (0);
494 Session::set_worst_io_latencies ()
496 _worst_output_latency = 0;
497 _worst_input_latency = 0;
499 if (!_engine.connected()) {
503 boost::shared_ptr<RouteList> r = routes.reader ();
505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
506 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
507 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
512 Session::when_engine_running ()
514 string first_physical_output;
516 BootMessage (_("Set block size and sample rate"));
518 set_block_size (_engine.frames_per_cycle());
519 set_frame_rate (_engine.frame_rate());
521 BootMessage (_("Using configuration"));
523 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
525 /* every time we reconnect, recompute worst case output latencies */
527 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
529 if (synced_to_jack()) {
530 _engine.transport_stop ();
533 if (config.get_jack_time_master()) {
534 _engine.transport_locate (_transport_frame);
542 _click_io.reset (new ClickIO (*this, "click"));
544 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
546 /* existing state for Click */
548 if (_click_io->set_state (*child->children().front()) == 0) {
550 _clicking = Config->get_clicking ();
554 error << _("could not setup Click I/O") << endmsg;
560 /* default state for Click: dual-mono to first 2 physical outputs */
562 for (int physport = 0; physport < 2; ++physport) {
563 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
565 if (physical_output.length()) {
566 if (_click_io->add_port (physical_output, this)) {
567 // relax, even though its an error
572 if (_click_io->n_ports () > ChanCount::ZERO) {
573 _clicking = Config->get_clicking ();
578 catch (failed_constructor& err) {
579 error << _("cannot setup Click I/O") << endmsg;
582 BootMessage (_("Compute I/O Latencies"));
584 set_worst_io_latencies ();
587 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
590 BootMessage (_("Set up standard connections"));
592 /* Create a set of Bundle objects that map
593 to the physical I/O currently available. We create both
594 mono and stereo bundles, so that the common cases of mono
595 and stereo tracks get bundles to put in their mixer strip
596 in / out menus. There may be a nicer way of achieving that;
597 it doesn't really scale that well to higher channel counts
600 /* mono output bundles */
602 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
604 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
606 shared_ptr<Bundle> c (new Bundle (buf, true));
607 c->add_channel (_("mono"));
608 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
613 /* stereo output bundles */
615 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
616 if (np + 1 < n_physical_outputs) {
618 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
619 shared_ptr<Bundle> c (new Bundle (buf, true));
620 c->add_channel (_("L"));
621 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
622 c->add_channel (_("R"));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
629 /* mono input bundles */
631 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
633 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
635 shared_ptr<Bundle> c (new Bundle (buf, false));
636 c->add_channel (_("mono"));
637 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
642 /* stereo input bundles */
644 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
645 if (np + 1 < n_physical_inputs) {
647 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
649 shared_ptr<Bundle> c (new Bundle (buf, false));
650 c->add_channel (_("L"));
651 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
652 c->add_channel (_("R"));
653 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
659 BootMessage (_("Setup signal flow and plugins"));
663 if (!no_auto_connect()) {
665 if (_master_out && Config->get_auto_connect_standard_busses()) {
667 /* if requested auto-connect the outputs to the first N physical ports.
670 uint32_t limit = _master_out->n_outputs().n_total();
672 for (uint32_t n = 0; n < limit; ++n) {
673 Port* p = _master_out->output()->nth (n);
674 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
676 if (!connect_to.empty()) {
677 if (_master_out->output()->connect (p, connect_to, this)) {
678 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
688 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
689 are undefined, at best.
692 /* control out listens to master bus (but ignores it
693 under some conditions)
696 uint32_t limit = _control_out->n_inputs().n_audio();
699 for (uint32_t n = 0; n < limit; ++n) {
700 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
701 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
704 string connect_to = o->name();
705 if (_control_out->input()->connect (p, connect_to, this)) {
706 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
714 /* if control out is not connected,
715 connect control out to physical outs, but use ones after the master if possible
718 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
720 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
722 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
725 _control_out->output()->connect_ports_to_bundle (b, this);
727 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
728 Config->get_monitor_bus_preferred_bundle())
734 /* XXX this logic is wrong for mixed port types */
736 uint32_t shift = _master_out->n_outputs().n_audio();
737 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
738 limit = _control_out->n_outputs().n_audio();
740 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
742 for (uint32_t n = 0; n < limit; ++n) {
744 Port* p = _control_out->output()->nth (n);
745 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
747 if (!connect_to.empty()) {
748 if (_control_out->output()->connect (p, connect_to, this)) {
749 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
760 /* catch up on send+insert cnts */
762 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
764 /* hook us up to the engine */
766 BootMessage (_("Connect to engine"));
768 _engine.set_session (this);
772 Session::hookup_io ()
774 /* stop graph reordering notifications from
775 causing resorts, etc.
778 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
783 /* we delay creating the auditioner till now because
784 it makes its own connections to ports.
785 the engine has to be running for this to work.
789 auditioner.reset (new Auditioner (*this));
792 catch (failed_constructor& err) {
793 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
797 /* load bundles, which we may have postponed earlier on */
798 if (_bundle_xml_node) {
799 load_bundles (*_bundle_xml_node);
800 delete _bundle_xml_node;
803 /* Tell all IO objects to connect themselves together */
805 IO::enable_connecting ();
807 /* Now reset all panners */
809 Delivery::reset_panners ();
811 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
815 boost::shared_ptr<RouteList> r = routes.reader ();
817 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
819 if ((*x)->is_control() || (*x)->is_master()) {
823 (*x)->listen_via (_control_out, false);
827 /* Anyone who cares about input state, wake up and do something */
829 IOConnectionsComplete (); /* EMIT SIGNAL */
831 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
833 /* now handle the whole enchilada as if it was one
839 /* update the full solo state, which can't be
840 correctly determined on a per-route basis, but
841 needs the global overview that only the session
845 update_route_solo_state ();
849 Session::playlist_length_changed ()
851 /* we can't just increase end_location->end() if pl->get_maximum_extent()
852 if larger. if the playlist used to be the longest playlist,
853 and its now shorter, we have to decrease end_location->end(). hence,
854 we have to iterate over all diskstreams and check the
855 playlists currently in use.
861 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
863 boost::shared_ptr<Playlist> playlist;
865 if ((playlist = dstream->playlist()) != 0) {
866 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
869 /* see comment in playlist_length_changed () */
874 Session::record_enabling_legal () const
876 /* this used to be in here, but survey says.... we don't need to restrict it */
877 // if (record_status() == Recording) {
881 if (Config->get_all_safe()) {
888 Session::reset_input_monitor_state ()
890 if (transport_rolling()) {
892 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if ((*i)->record_enabled ()) {
896 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
897 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
901 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
903 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
904 if ((*i)->record_enabled ()) {
905 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
906 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
913 Session::auto_punch_start_changed (Location* location)
915 replace_event (Event::PunchIn, location->start());
917 if (get_record_enabled() && config.get_punch_in()) {
918 /* capture start has been changed, so save new pending state */
919 save_state ("", true);
924 Session::auto_punch_end_changed (Location* location)
926 nframes_t when_to_stop = location->end();
927 // when_to_stop += _worst_output_latency + _worst_input_latency;
928 replace_event (Event::PunchOut, when_to_stop);
932 Session::auto_punch_changed (Location* location)
934 nframes_t when_to_stop = location->end();
936 replace_event (Event::PunchIn, location->start());
937 //when_to_stop += _worst_output_latency + _worst_input_latency;
938 replace_event (Event::PunchOut, when_to_stop);
942 Session::auto_loop_changed (Location* location)
944 replace_event (Event::AutoLoop, location->end(), location->start());
946 if (transport_rolling() && play_loop) {
948 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
950 if (_transport_frame > location->end()) {
951 // relocate to beginning of loop
952 clear_events (Event::LocateRoll);
954 request_locate (location->start(), true);
957 else if (Config->get_seamless_loop() && !loop_changing) {
959 // schedule a locate-roll to refill the diskstreams at the
961 loop_changing = true;
963 if (location->end() > last_loopend) {
964 clear_events (Event::LocateRoll);
965 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
972 last_loopend = location->end();
976 Session::set_auto_punch_location (Location* location)
980 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
981 auto_punch_start_changed_connection.disconnect();
982 auto_punch_end_changed_connection.disconnect();
983 auto_punch_changed_connection.disconnect();
984 existing->set_auto_punch (false, this);
985 remove_event (existing->start(), Event::PunchIn);
986 clear_events (Event::PunchOut);
987 auto_punch_location_changed (0);
996 if (location->end() <= location->start()) {
997 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1001 auto_punch_start_changed_connection.disconnect();
1002 auto_punch_end_changed_connection.disconnect();
1003 auto_punch_changed_connection.disconnect();
1005 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1006 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1007 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1009 location->set_auto_punch (true, this);
1012 auto_punch_changed (location);
1014 auto_punch_location_changed (location);
1018 Session::set_auto_loop_location (Location* location)
1022 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1023 auto_loop_start_changed_connection.disconnect();
1024 auto_loop_end_changed_connection.disconnect();
1025 auto_loop_changed_connection.disconnect();
1026 existing->set_auto_loop (false, this);
1027 remove_event (existing->end(), Event::AutoLoop);
1028 auto_loop_location_changed (0);
1033 if (location == 0) {
1037 if (location->end() <= location->start()) {
1038 error << _("Session: you can't use a mark for auto loop") << endmsg;
1042 last_loopend = location->end();
1044 auto_loop_start_changed_connection.disconnect();
1045 auto_loop_end_changed_connection.disconnect();
1046 auto_loop_changed_connection.disconnect();
1048 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1049 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1050 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1052 location->set_auto_loop (true, this);
1054 /* take care of our stuff first */
1056 auto_loop_changed (location);
1058 /* now tell everyone else */
1060 auto_loop_location_changed (location);
1064 Session::locations_added (Location* ignored)
1070 Session::locations_changed ()
1072 _locations.apply (*this, &Session::handle_locations_changed);
1076 Session::handle_locations_changed (Locations::LocationList& locations)
1078 Locations::LocationList::iterator i;
1080 bool set_loop = false;
1081 bool set_punch = false;
1083 for (i = locations.begin(); i != locations.end(); ++i) {
1087 if (location->is_auto_punch()) {
1088 set_auto_punch_location (location);
1091 if (location->is_auto_loop()) {
1092 set_auto_loop_location (location);
1096 if (location->is_start()) {
1097 start_location = location;
1099 if (location->is_end()) {
1100 end_location = location;
1105 set_auto_loop_location (0);
1108 set_auto_punch_location (0);
1115 Session::enable_record ()
1117 /* XXX really atomic compare+swap here */
1118 if (g_atomic_int_get (&_record_status) != Recording) {
1119 g_atomic_int_set (&_record_status, Recording);
1120 _last_record_location = _transport_frame;
1121 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1123 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1124 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1125 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1126 if ((*i)->record_enabled ()) {
1127 (*i)->monitor_input (true);
1132 RecordStateChanged ();
1137 Session::disable_record (bool rt_context, bool force)
1141 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1143 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1144 g_atomic_int_set (&_record_status, Disabled);
1146 if (rs == Recording) {
1147 g_atomic_int_set (&_record_status, Enabled);
1151 // FIXME: timestamp correct? [DR]
1152 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1153 // does this /need/ to be sent in all cases?
1155 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1157 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1158 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1160 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1161 if ((*i)->record_enabled ()) {
1162 (*i)->monitor_input (false);
1167 RecordStateChanged (); /* emit signal */
1170 remove_pending_capture_state ();
1176 Session::step_back_from_record ()
1178 /* XXX really atomic compare+swap here */
1179 if (g_atomic_int_get (&_record_status) == Recording) {
1180 g_atomic_int_set (&_record_status, Enabled);
1182 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1186 if ((*i)->record_enabled ()) {
1187 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1188 (*i)->monitor_input (false);
1196 Session::maybe_enable_record ()
1198 g_atomic_int_set (&_record_status, Enabled);
1200 /* this function is currently called from somewhere other than an RT thread.
1201 this save_state() call therefore doesn't impact anything.
1204 save_state ("", true);
1206 if (_transport_speed) {
1207 if (!config.get_punch_in()) {
1211 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1212 RecordStateChanged (); /* EMIT SIGNAL */
1219 Session::audible_frame () const
1225 /* the first of these two possible settings for "offset"
1226 mean that the audible frame is stationary until
1227 audio emerges from the latency compensation
1230 the second means that the audible frame is stationary
1231 until audio would emerge from a physical port
1232 in the absence of any plugin latency compensation
1235 offset = _worst_output_latency;
1237 if (offset > current_block_size) {
1238 offset -= current_block_size;
1240 /* XXX is this correct? if we have no external
1241 physical connections and everything is internal
1242 then surely this is zero? still, how
1243 likely is that anyway?
1245 offset = current_block_size;
1248 if (synced_to_jack()) {
1249 tf = _engine.transport_frame();
1251 tf = _transport_frame;
1256 if (!non_realtime_work_pending()) {
1260 /* check to see if we have passed the first guaranteed
1261 audible frame past our last start position. if not,
1262 return that last start point because in terms
1263 of audible frames, we have not moved yet.
1266 if (_transport_speed > 0.0f) {
1268 if (!play_loop || !have_looped) {
1269 if (tf < _last_roll_location + offset) {
1270 return _last_roll_location;
1278 } else if (_transport_speed < 0.0f) {
1280 /* XXX wot? no backward looping? */
1282 if (tf > _last_roll_location - offset) {
1283 return _last_roll_location;
1295 Session::set_frame_rate (nframes_t frames_per_second)
1297 /** \fn void Session::set_frame_size(nframes_t)
1298 the AudioEngine object that calls this guarantees
1299 that it will not be called while we are also in
1300 ::process(). Its fine to do things that block
1304 _base_frame_rate = frames_per_second;
1308 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1312 // XXX we need some equivalent to this, somehow
1313 // SndFileSource::setup_standard_crossfades (frames_per_second);
1317 /* XXX need to reset/reinstantiate all LADSPA plugins */
1321 Session::set_block_size (nframes_t nframes)
1323 /* the AudioEngine guarantees
1324 that it will not be called while we are also in
1325 ::process(). It is therefore fine to do things that block
1330 current_block_size = nframes;
1332 ensure_buffers(_scratch_buffers->available());
1334 delete [] _gain_automation_buffer;
1335 _gain_automation_buffer = new gain_t[nframes];
1337 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1339 boost::shared_ptr<RouteList> r = routes.reader ();
1341 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1342 (*i)->set_block_size (nframes);
1345 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1346 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1347 (*i)->set_block_size (nframes);
1350 set_worst_io_latencies ();
1355 Session::set_default_fade (float steepness, float fade_msecs)
1358 nframes_t fade_frames;
1360 /* Don't allow fade of less 1 frame */
1362 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1369 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1373 default_fade_msecs = fade_msecs;
1374 default_fade_steepness = steepness;
1377 // jlc, WTF is this!
1378 Glib::RWLock::ReaderLock lm (route_lock);
1379 AudioRegion::set_default_fade (steepness, fade_frames);
1384 /* XXX have to do this at some point */
1385 /* foreach region using default fade, reset, then
1386 refill_all_diskstream_buffers ();
1391 struct RouteSorter {
1392 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1393 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1395 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1398 if (r1->fed_by.empty()) {
1399 if (r2->fed_by.empty()) {
1400 /* no ardour-based connections inbound to either route. just use signal order */
1401 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1403 /* r2 has connections, r1 does not; run r1 early */
1407 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1414 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1416 shared_ptr<Route> r2;
1418 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1419 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1423 /* make a copy of the existing list of routes that feed r1 */
1425 set<shared_ptr<Route> > existing = r1->fed_by;
1427 /* for each route that feeds r1, recurse, marking it as feeding
1431 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1434 /* r2 is a route that feeds r1 which somehow feeds base. mark
1435 base as being fed by r2
1438 rbase->fed_by.insert (r2);
1442 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1446 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1450 /* now recurse, so that we can mark base as being fed by
1451 all routes that feed r2
1454 trace_terminal (r2, rbase);
1461 Session::resort_routes ()
1463 /* don't do anything here with signals emitted
1464 by Routes while we are being destroyed.
1467 if (_state_of_the_state & Deletion) {
1474 RCUWriter<RouteList> writer (routes);
1475 shared_ptr<RouteList> r = writer.get_copy ();
1476 resort_routes_using (r);
1477 /* writer goes out of scope and forces update */
1482 Session::resort_routes_using (shared_ptr<RouteList> r)
1484 RouteList::iterator i, j;
1486 for (i = r->begin(); i != r->end(); ++i) {
1488 (*i)->fed_by.clear ();
1490 for (j = r->begin(); j != r->end(); ++j) {
1492 /* although routes can feed themselves, it will
1493 cause an endless recursive descent if we
1494 detect it. so don't bother checking for
1502 if ((*j)->feeds (*i)) {
1503 (*i)->fed_by.insert (*j);
1508 for (i = r->begin(); i != r->end(); ++i) {
1509 trace_terminal (*i, *i);
1516 cerr << "finished route resort\n";
1518 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1519 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1526 list<boost::shared_ptr<MidiTrack> >
1527 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1529 char track_name[32];
1530 uint32_t track_id = 0;
1533 RouteList new_routes;
1534 list<boost::shared_ptr<MidiTrack> > ret;
1535 //uint32_t control_id;
1537 // FIXME: need physical I/O and autoconnect stuff for MIDI
1539 /* count existing midi tracks */
1542 shared_ptr<RouteList> r = routes.reader ();
1544 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1545 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1546 if (!(*i)->is_hidden()) {
1548 //channels_used += (*i)->n_inputs().n_midi();
1554 vector<string> physinputs;
1555 vector<string> physoutputs;
1557 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1558 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1560 // control_id = ntracks() + nbusses();
1564 /* check for duplicate route names, since we might have pre-existing
1565 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1566 save, close,restart,add new route - first named route is now
1574 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1576 if (route_by_name (track_name) == 0) {
1580 } while (track_id < (UINT_MAX-1));
1582 shared_ptr<MidiTrack> track;
1585 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1587 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1588 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1593 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1594 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1600 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1604 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1605 port = physinputs[(channels_used+x)%nphysical_in];
1608 if (port.length() && track->connect_input (track->input (x), port, this)) {
1614 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1618 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1619 port = physoutputs[(channels_used+x)%nphysical_out];
1620 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1622 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1626 if (port.length() && track->connect_output (track->output (x), port, this)) {
1631 channels_used += track->n_inputs ().n_midi();
1635 track->midi_diskstream()->non_realtime_input_change();
1636 track->set_route_group (route_group, 0);
1638 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1639 //track->set_remote_control_id (control_id);
1641 new_routes.push_back (track);
1642 ret.push_back (track);
1645 catch (failed_constructor &err) {
1646 error << _("Session: could not create new midi track.") << endmsg;
1649 /* we need to get rid of this, since the track failed to be created */
1650 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1653 RCUWriter<DiskstreamList> writer (diskstreams);
1654 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1655 ds->remove (track->midi_diskstream());
1662 catch (AudioEngine::PortRegistrationFailure& pfe) {
1664 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;
1667 /* we need to get rid of this, since the track failed to be created */
1668 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1671 RCUWriter<DiskstreamList> writer (diskstreams);
1672 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1673 ds->remove (track->midi_diskstream());
1684 if (!new_routes.empty()) {
1685 add_routes (new_routes, false);
1686 save_state (_current_snapshot_name);
1692 list<boost::shared_ptr<AudioTrack> >
1693 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1695 char track_name[32];
1696 uint32_t track_id = 0;
1698 uint32_t channels_used = 0;
1700 RouteList new_routes;
1701 list<boost::shared_ptr<AudioTrack> > ret;
1702 uint32_t control_id;
1704 /* count existing audio tracks */
1707 shared_ptr<RouteList> r = routes.reader ();
1709 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1710 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1711 if (!(*i)->is_hidden()) {
1713 channels_used += (*i)->n_inputs().n_audio();
1719 vector<string> physinputs;
1720 vector<string> physoutputs;
1722 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1723 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1725 control_id = ntracks() + nbusses() + 1;
1729 /* check for duplicate route names, since we might have pre-existing
1730 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1731 save, close,restart,add new route - first named route is now
1739 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1741 if (route_by_name (track_name) == 0) {
1745 } while (track_id < (UINT_MAX-1));
1747 shared_ptr<AudioTrack> track;
1750 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1752 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1753 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1754 input_channels, output_channels)
1759 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1760 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1761 input_channels, output_channels)
1766 if (!physinputs.empty()) {
1767 uint32_t nphysical_in = physinputs.size();
1769 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1773 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1774 port = physinputs[(channels_used+x)%nphysical_in];
1777 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1783 if (!physoutputs.empty()) {
1784 uint32_t nphysical_out = physoutputs.size();
1786 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1789 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1790 port = physoutputs[(channels_used+x)%nphysical_out];
1791 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1792 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1793 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1797 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1803 channels_used += track->n_inputs ().n_audio();
1805 track->set_route_group (route_group, 0);
1807 track->audio_diskstream()->non_realtime_input_change();
1809 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1810 track->set_remote_control_id (control_id);
1813 new_routes.push_back (track);
1814 ret.push_back (track);
1817 catch (failed_constructor &err) {
1818 error << _("Session: could not create new audio track.") << endmsg;
1821 /* we need to get rid of this, since the track failed to be created */
1822 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1825 RCUWriter<DiskstreamList> writer (diskstreams);
1826 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1827 ds->remove (track->audio_diskstream());
1834 catch (AudioEngine::PortRegistrationFailure& pfe) {
1836 error << pfe.what() << endmsg;
1839 /* we need to get rid of this, since the track failed to be created */
1840 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1843 RCUWriter<DiskstreamList> writer (diskstreams);
1844 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1845 ds->remove (track->audio_diskstream());
1856 if (!new_routes.empty()) {
1857 add_routes (new_routes, true);
1864 Session::set_remote_control_ids ()
1866 RemoteModel m = Config->get_remote_model();
1868 shared_ptr<RouteList> r = routes.reader ();
1870 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1871 if ( MixerOrdered == m) {
1872 long order = (*i)->order_key(N_("signal"));
1873 (*i)->set_remote_control_id( order+1 );
1874 } else if ( EditorOrdered == m) {
1875 long order = (*i)->order_key(N_("editor"));
1876 (*i)->set_remote_control_id( order+1 );
1877 } else if ( UserOrdered == m) {
1878 //do nothing ... only changes to remote id's are initiated by user
1885 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1888 uint32_t bus_id = 1;
1890 uint32_t channels_used = 0;
1893 uint32_t control_id;
1895 /* count existing audio busses */
1898 shared_ptr<RouteList> r = routes.reader ();
1900 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1901 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1903 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1906 channels_used += (*i)->n_inputs().n_audio();
1912 vector<string> physinputs;
1913 vector<string> physoutputs;
1915 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1916 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1918 n_physical_audio_outputs = physoutputs.size();
1919 n_physical_audio_inputs = physinputs.size();
1921 control_id = ntracks() + nbusses() + 1;
1926 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1930 if (route_by_name (bus_name) == 0) {
1934 } while (bus_id < (UINT_MAX-1));
1937 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1939 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1940 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1941 input_channels, output_channels)
1947 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1948 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1949 input_channels, output_channels)
1954 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1957 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1958 port = physinputs[((n+x)%n_physical_audio_inputs)];
1961 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1966 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1969 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1970 port = physoutputs[((n+x)%n_physical_outputs)];
1971 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1973 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1977 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1982 channels_used += bus->n_inputs ().n_audio();
1984 bus->set_route_group (route_group, 0);
1985 bus->set_remote_control_id (control_id);
1988 ret.push_back (bus);
1992 catch (failed_constructor &err) {
1993 error << _("Session: could not create new audio route.") << endmsg;
1997 catch (AudioEngine::PortRegistrationFailure& pfe) {
1998 error << pfe.what() << endmsg;
2008 add_routes (ret, true);
2016 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2020 uint32_t control_id;
2023 if (!tree.read (template_path.c_str())) {
2027 XMLNode* node = tree.root();
2029 control_id = ntracks() + nbusses() + 1;
2033 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2035 std::string node_name = IO::name_from_state (*node_copy.children().front());
2037 if (route_by_name (node_name) != 0) {
2039 /* generate a new name by adding a number to the end of the template name */
2041 uint32_t number = 1;
2044 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2048 if (route_by_name (name) == 0) {
2052 } while (number < UINT_MAX);
2054 if (number == UINT_MAX) {
2055 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2059 IO::set_name_in_state (*node_copy.children().front(), name);
2062 Track::zero_diskstream_id_in_xml (node_copy);
2065 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2068 error << _("Session: cannot create track/bus from template description") << endmsg;
2072 if (boost::dynamic_pointer_cast<Track>(route)) {
2073 /* force input/output change signals so that the new diskstream
2074 picks up the configuration of the route. During session
2075 loading this normally happens in a different way.
2077 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2078 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2081 route->set_remote_control_id (control_id);
2084 ret.push_back (route);
2087 catch (failed_constructor &err) {
2088 error << _("Session: could not create new route from template") << endmsg;
2092 catch (AudioEngine::PortRegistrationFailure& pfe) {
2093 error << pfe.what() << endmsg;
2102 add_routes (ret, true);
2109 Session::add_routes (RouteList& new_routes, bool save)
2112 RCUWriter<RouteList> writer (routes);
2113 shared_ptr<RouteList> r = writer.get_copy ();
2114 r->insert (r->end(), new_routes.begin(), new_routes.end());
2117 /* if there is no control out and we're not in the middle of loading,
2118 resort the graph here. if there is a control out, we will resort
2119 toward the end of this method. if we are in the middle of loading,
2120 we will resort when done.
2123 if (!_control_out && IO::connecting_legal) {
2124 resort_routes_using (r);
2128 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2130 boost::weak_ptr<Route> wpr (*x);
2132 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2133 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2134 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2135 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2136 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2137 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2139 if ((*x)->is_master()) {
2143 if ((*x)->is_control()) {
2144 _control_out = (*x);
2148 if (_control_out && IO::connecting_legal) {
2150 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2151 if ((*x)->is_control() || (*x)->is_master()) {
2154 cerr << "Add listen via control outs\n";
2155 (*x)->listen_via (_control_out, false);
2164 save_state (_current_snapshot_name);
2167 RouteAdded (new_routes); /* EMIT SIGNAL */
2171 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest)
2173 boost::shared_ptr<RouteList> r = routes.reader ();
2174 boost::shared_ptr<RouteList> t (new RouteList);
2176 /* only send tracks */
2178 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2179 if (boost::dynamic_pointer_cast<Track>(*i)) {
2184 add_internal_sends (dest, t);
2188 Session::add_internal_sends (boost::shared_ptr<Route> dest, boost::shared_ptr<RouteList> senders)
2190 if (dest->is_control() || dest->is_master()) {
2194 if (!dest->internal_return()) {
2195 dest->add_internal_return();
2198 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2200 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2204 (*i)->listen_via (dest, true);
2209 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2211 /* need to do this in case we're rolling at the time, to prevent false underruns */
2212 dstream->do_refill_with_alloc ();
2214 dstream->set_block_size (current_block_size);
2217 RCUWriter<DiskstreamList> writer (diskstreams);
2218 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2219 ds->push_back (dstream);
2220 /* writer goes out of scope, copies ds back to main */
2223 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2224 /* this will connect to future changes, and check the current length */
2225 diskstream_playlist_changed (dstream);
2227 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2229 dstream->prepare ();
2234 Session::remove_route (shared_ptr<Route> route)
2237 RCUWriter<RouteList> writer (routes);
2238 shared_ptr<RouteList> rs = writer.get_copy ();
2242 /* deleting the master out seems like a dumb
2243 idea, but its more of a UI policy issue
2247 if (route == _master_out) {
2248 _master_out = shared_ptr<Route> ();
2251 if (route == _control_out) {
2253 /* cancel control outs for all routes */
2255 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2256 (*r)->drop_listen (_control_out);
2259 _control_out.reset ();
2262 update_route_solo_state ();
2264 /* writer goes out of scope, forces route list update */
2267 boost::shared_ptr<Track> t;
2268 boost::shared_ptr<Diskstream> ds;
2270 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2271 ds = t->diskstream();
2277 RCUWriter<DiskstreamList> dsl (diskstreams);
2278 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2283 find_current_end ();
2285 // We need to disconnect the routes inputs and outputs
2287 route->input()->disconnect (0);
2288 route->output()->disconnect (0);
2290 update_latency_compensation (false, false);
2293 /* get rid of it from the dead wood collection in the route list manager */
2295 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2299 /* try to cause everyone to drop their references */
2301 route->drop_references ();
2303 sync_order_keys (N_("session"));
2305 /* save the new state of the world */
2307 if (save_state (_current_snapshot_name)) {
2308 save_history (_current_snapshot_name);
2313 Session::route_mute_changed (void* src)
2319 Session::route_listen_changed (void* src, boost::weak_ptr<Route> wpr)
2321 boost::shared_ptr<Route> route = wpr.lock();
2323 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2327 if (route->listening()) {
2329 } else if (_listen_cnt > 0) {
2335 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2337 if (solo_update_disabled) {
2342 boost::shared_ptr<Route> route = wpr.lock ();
2345 /* should not happen */
2346 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2350 shared_ptr<RouteList> r = routes.reader ();
2353 if (route->soloed()) {
2359 /* now mod the solo level of all other routes except master & control outs
2360 so that they will be silent if appropriate.
2363 solo_update_disabled = true;
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2366 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2368 (*i)->mod_solo_level (delta);
2372 /* make sure master is never muted by solo */
2374 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2375 _master_out->mod_solo_level (1);
2378 /* ditto for control outs make sure master is never muted by solo */
2380 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2381 _control_out->mod_solo_level (1);
2384 solo_update_disabled = false;
2385 update_route_solo_state (r);
2386 SoloChanged (); /* EMIT SIGNAL */
2391 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2393 /* now figure out if anything that matters is soloed */
2395 bool something_soloed = false;
2398 r = routes.reader();
2401 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2402 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2403 something_soloed = true;
2408 if (something_soloed != _non_soloed_outs_muted) {
2409 _non_soloed_outs_muted = something_soloed;
2410 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2415 Session::route_by_name (string name)
2417 shared_ptr<RouteList> r = routes.reader ();
2419 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2420 if ((*i)->name() == name) {
2425 return shared_ptr<Route> ((Route*) 0);
2429 Session::route_by_id (PBD::ID id)
2431 shared_ptr<RouteList> r = routes.reader ();
2433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2434 if ((*i)->id() == id) {
2439 return shared_ptr<Route> ((Route*) 0);
2443 Session::route_by_remote_id (uint32_t id)
2445 shared_ptr<RouteList> r = routes.reader ();
2447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2448 if ((*i)->remote_control_id() == id) {
2453 return shared_ptr<Route> ((Route*) 0);
2457 Session::find_current_end ()
2459 if (_state_of_the_state & Loading) {
2463 nframes_t max = get_maximum_extent ();
2465 if (max > end_location->end()) {
2466 end_location->set_end (max);
2468 DurationChanged(); /* EMIT SIGNAL */
2473 Session::get_maximum_extent () const
2478 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2480 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2481 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2483 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2484 if ((me = pl->get_maximum_extent()) > max) {
2492 boost::shared_ptr<Diskstream>
2493 Session::diskstream_by_name (string name)
2495 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2497 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2498 if ((*i)->name() == name) {
2503 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2506 boost::shared_ptr<Diskstream>
2507 Session::diskstream_by_id (const PBD::ID& id)
2509 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2511 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2512 if ((*i)->id() == id) {
2517 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2520 /* Region management */
2523 Session::new_region_name (string old)
2525 string::size_type last_period;
2527 string::size_type len = old.length() + 64;
2530 if ((last_period = old.find_last_of ('.')) == string::npos) {
2532 /* no period present - add one explicitly */
2535 last_period = old.length() - 1;
2540 number = atoi (old.substr (last_period+1).c_str());
2544 while (number < (UINT_MAX-1)) {
2546 RegionList::const_iterator i;
2551 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2554 for (i = regions.begin(); i != regions.end(); ++i) {
2555 if (i->second->name() == sbuf) {
2560 if (i == regions.end()) {
2565 if (number != (UINT_MAX-1)) {
2569 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2574 Session::region_name (string& result, string base, bool newlevel)
2579 if (base.find("/") != string::npos) {
2580 base = base.substr(base.find_last_of("/") + 1);
2585 Glib::Mutex::Lock lm (region_lock);
2587 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2596 string::size_type pos;
2598 pos = base.find_last_of ('.');
2600 /* pos may be npos, but then we just use entire base */
2602 subbase = base.substr (0, pos);
2607 Glib::Mutex::Lock lm (region_lock);
2609 map<string,uint32_t>::iterator x;
2613 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2615 region_name_map[subbase] = 1;
2618 snprintf (buf, sizeof (buf), ".%d", x->second);
2629 Session::add_region (boost::shared_ptr<Region> region)
2631 vector<boost::shared_ptr<Region> > v;
2632 v.push_back (region);
2637 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2642 Glib::Mutex::Lock lm (region_lock);
2644 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2646 boost::shared_ptr<Region> region = *ii;
2650 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2654 RegionList::iterator x;
2656 for (x = regions.begin(); x != regions.end(); ++x) {
2658 if (region->region_list_equivalent (x->second)) {
2663 if (x == regions.end()) {
2665 pair<RegionList::key_type,RegionList::mapped_type> entry;
2667 entry.first = region->id();
2668 entry.second = region;
2670 pair<RegionList::iterator,bool> x = regions.insert (entry);
2682 /* mark dirty because something has changed even if we didn't
2683 add the region to the region list.
2690 vector<boost::weak_ptr<Region> > v;
2691 boost::shared_ptr<Region> first_r;
2693 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2695 boost::shared_ptr<Region> region = *ii;
2699 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2702 v.push_back (region);
2709 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2710 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2712 update_region_name_map (region);
2716 RegionsAdded (v); /* EMIT SIGNAL */
2722 Session::update_region_name_map (boost::shared_ptr<Region> region)
2724 string::size_type last_period = region->name().find_last_of ('.');
2726 if (last_period != string::npos && last_period < region->name().length() - 1) {
2728 string base = region->name().substr (0, last_period);
2729 string number = region->name().substr (last_period+1);
2730 map<string,uint32_t>::iterator x;
2732 /* note that if there is no number, we get zero from atoi,
2736 region_name_map[base] = atoi (number);
2741 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2743 boost::shared_ptr<Region> region (weak_region.lock ());
2749 if (what_changed & Region::HiddenChanged) {
2750 /* relay hidden changes */
2751 RegionHiddenChange (region);
2754 if (what_changed & NameChanged) {
2755 update_region_name_map (region);
2760 Session::remove_region (boost::weak_ptr<Region> weak_region)
2762 RegionList::iterator i;
2763 boost::shared_ptr<Region> region (weak_region.lock ());
2769 bool removed = false;
2772 Glib::Mutex::Lock lm (region_lock);
2774 if ((i = regions.find (region->id())) != regions.end()) {
2780 /* mark dirty because something has changed even if we didn't
2781 remove the region from the region list.
2787 RegionRemoved(region); /* EMIT SIGNAL */
2791 boost::shared_ptr<Region>
2792 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2794 RegionList::iterator i;
2795 boost::shared_ptr<Region> region;
2797 Glib::Mutex::Lock lm (region_lock);
2799 for (i = regions.begin(); i != regions.end(); ++i) {
2803 if (region->whole_file()) {
2805 if (child->source_equivalent (region)) {
2811 return boost::shared_ptr<Region> ();
2815 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2817 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2818 (*i)->get_region_list_equivalent_regions (region, result);
2822 Session::destroy_region (boost::shared_ptr<Region> region)
2824 vector<boost::shared_ptr<Source> > srcs;
2827 if (region->playlist()) {
2828 region->playlist()->destroy_region (region);
2831 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2832 srcs.push_back (region->source (n));
2836 region->drop_references ();
2838 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2840 (*i)->mark_for_remove ();
2841 (*i)->drop_references ();
2843 cerr << "source was not used by any playlist\n";
2850 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2852 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2853 destroy_region (*i);
2859 Session::remove_last_capture ()
2861 list<boost::shared_ptr<Region> > r;
2863 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2865 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2866 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2869 r.insert (r.end(), l.begin(), l.end());
2874 destroy_regions (r);
2876 save_state (_current_snapshot_name);
2882 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2888 /* Source Management */
2891 Session::add_source (boost::shared_ptr<Source> source)
2893 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2894 pair<SourceMap::iterator,bool> result;
2896 entry.first = source->id();
2897 entry.second = source;
2900 Glib::Mutex::Lock lm (source_lock);
2901 result = sources.insert (entry);
2904 if (result.second) {
2905 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2909 boost::shared_ptr<AudioFileSource> afs;
2911 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2912 if (Config->get_auto_analyse_audio()) {
2913 Analyser::queue_source_for_analysis (source, false);
2919 Session::remove_source (boost::weak_ptr<Source> src)
2921 SourceMap::iterator i;
2922 boost::shared_ptr<Source> source = src.lock();
2929 Glib::Mutex::Lock lm (source_lock);
2931 if ((i = sources.find (source->id())) != sources.end()) {
2936 if (!_state_of_the_state & InCleanup) {
2938 /* save state so we don't end up with a session file
2939 referring to non-existent sources.
2942 save_state (_current_snapshot_name);
2946 boost::shared_ptr<Source>
2947 Session::source_by_id (const PBD::ID& id)
2949 Glib::Mutex::Lock lm (source_lock);
2950 SourceMap::iterator i;
2951 boost::shared_ptr<Source> source;
2953 if ((i = sources.find (id)) != sources.end()) {
2960 boost::shared_ptr<Source>
2961 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2963 Glib::Mutex::Lock lm (source_lock);
2965 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2966 cerr << "comparing " << path << " with " << i->second->name() << endl;
2967 boost::shared_ptr<AudioFileSource> afs
2968 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2970 if (afs && afs->path() == path && chn == afs->channel()) {
2974 return boost::shared_ptr<Source>();
2979 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2982 string old_basename = PBD::basename_nosuffix (oldname);
2983 string new_legalized = legalize_for_path (newname);
2985 /* note: we know (or assume) the old path is already valid */
2989 /* destructive file sources have a name of the form:
2991 /path/to/Tnnnn-NAME(%[LR])?.wav
2993 the task here is to replace NAME with the new name.
2996 /* find last slash */
3000 string::size_type slash;
3001 string::size_type dash;
3003 if ((slash = path.find_last_of ('/')) == string::npos) {
3007 dir = path.substr (0, slash+1);
3009 /* '-' is not a legal character for the NAME part of the path */
3011 if ((dash = path.find_last_of ('-')) == string::npos) {
3015 prefix = path.substr (slash+1, dash-(slash+1));
3020 path += new_legalized;
3021 path += ".wav"; /* XXX gag me with a spoon */
3025 /* non-destructive file sources have a name of the form:
3027 /path/to/NAME-nnnnn(%[LR])?.ext
3029 the task here is to replace NAME with the new name.
3034 string::size_type slash;
3035 string::size_type dash;
3036 string::size_type postfix;
3038 /* find last slash */
3040 if ((slash = path.find_last_of ('/')) == string::npos) {
3044 dir = path.substr (0, slash+1);
3046 /* '-' is not a legal character for the NAME part of the path */
3048 if ((dash = path.find_last_of ('-')) == string::npos) {
3052 suffix = path.substr (dash+1);
3054 // Suffix is now everything after the dash. Now we need to eliminate
3055 // the nnnnn part, which is done by either finding a '%' or a '.'
3057 postfix = suffix.find_last_of ("%");
3058 if (postfix == string::npos) {
3059 postfix = suffix.find_last_of ('.');
3062 if (postfix != string::npos) {
3063 suffix = suffix.substr (postfix);
3065 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3069 const uint32_t limit = 10000;
3070 char buf[PATH_MAX+1];
3072 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3074 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3076 if (access (buf, F_OK) != 0) {
3084 error << "FATAL ERROR! Could not find a " << endl;
3092 /** Return the full path (in some session directory) for a new embedded source.
3093 * \a name must be a session-unique name that does not contain slashes
3094 * (e.g. as returned by new_*_source_name)
3097 Session::new_source_path_from_name (DataType type, const string& name)
3099 assert(name.find("/") == string::npos);
3101 SessionDirectory sdir(get_best_session_directory_for_new_source());
3104 if (type == DataType::AUDIO) {
3105 p = sdir.sound_path();
3106 } else if (type == DataType::MIDI) {
3107 p = sdir.midi_path();
3109 error << "Unknown source type, unable to create file path" << endmsg;
3114 return p.to_string();
3118 Session::peak_path (Glib::ustring base) const
3120 sys::path peakfile_path(_session_dir->peak_path());
3121 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3122 return peakfile_path.to_string();
3125 /** Return a unique name based on \a base for a new internal audio source */
3127 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3131 char buf[PATH_MAX+1];
3132 const uint32_t limit = 10000;
3136 legalized = legalize_for_path (base);
3138 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3139 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3141 vector<space_and_path>::iterator i;
3142 uint32_t existing = 0;
3144 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3146 SessionDirectory sdir((*i).path);
3148 spath = sdir.sound_path().to_string();
3153 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3154 spath.c_str(), cnt, legalized.c_str());
3155 } else if (nchan == 2) {
3157 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3158 spath.c_str(), cnt, legalized.c_str());
3160 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3161 spath.c_str(), cnt, legalized.c_str());
3163 } else if (nchan < 26) {
3164 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3165 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3167 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3168 spath.c_str(), cnt, legalized.c_str());
3177 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3178 } else if (nchan == 2) {
3180 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3182 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3184 } else if (nchan < 26) {
3185 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3187 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3191 if (sys::exists(buf)) {
3197 if (existing == 0) {
3202 error << string_compose(
3203 _("There are already %1 recordings for %2, which I consider too many."),
3204 limit, base) << endmsg;
3206 throw failed_constructor();
3210 return Glib::path_get_basename(buf);
3213 /** Create a new embedded audio source */
3214 boost::shared_ptr<AudioFileSource>
3215 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3217 const size_t n_chans = ds.n_channels().n_audio();
3218 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3219 const string path = new_source_path_from_name(DataType::AUDIO, name);
3220 return boost::dynamic_pointer_cast<AudioFileSource> (
3221 SourceFactory::createWritable (
3222 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3225 /** Return a unique name based on \a base for a new internal MIDI source */
3227 Session::new_midi_source_name (const string& base)
3230 char buf[PATH_MAX+1];
3231 const uint32_t limit = 10000;
3235 legalized = legalize_for_path (base);
3237 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3238 for (cnt = 1; cnt <= limit; ++cnt) {
3240 vector<space_and_path>::iterator i;
3241 uint32_t existing = 0;
3243 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3245 SessionDirectory sdir((*i).path);
3247 sys::path p = sdir.midi_path();
3250 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3252 if (sys::exists (buf)) {
3257 if (existing == 0) {
3262 error << string_compose(
3263 _("There are already %1 recordings for %2, which I consider too many."),
3264 limit, base) << endmsg;
3266 throw failed_constructor();
3270 return Glib::path_get_basename(buf);
3274 /** Create a new embedded MIDI source */
3275 boost::shared_ptr<MidiSource>
3276 Session::create_midi_source_for_session (MidiDiskstream& ds)
3278 const string name = new_midi_source_name (ds.name());
3279 const string path = new_source_path_from_name (DataType::MIDI, name);
3281 return boost::dynamic_pointer_cast<SMFSource> (
3282 SourceFactory::createWritable (
3283 DataType::MIDI, *this, path, true, false, frame_rate()));
3287 /* Playlist management */
3289 boost::shared_ptr<Playlist>
3290 Session::playlist_by_name (string name)
3292 Glib::Mutex::Lock lm (playlist_lock);
3293 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3294 if ((*i)->name() == name) {
3298 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3299 if ((*i)->name() == name) {
3304 return boost::shared_ptr<Playlist>();
3308 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3310 Glib::Mutex::Lock lm (playlist_lock);
3311 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3312 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3313 list.push_back (*i);
3316 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3317 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3318 list.push_back (*i);
3324 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3326 if (playlist->hidden()) {
3331 Glib::Mutex::Lock lm (playlist_lock);
3332 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3333 playlists.insert (playlists.begin(), playlist);
3334 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3335 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3340 playlist->release();
3345 PlaylistAdded (playlist); /* EMIT SIGNAL */
3349 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3352 Glib::Mutex::Lock lm (playlist_lock);
3353 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3356 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3363 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3365 boost::shared_ptr<Playlist> pl(wpl.lock());
3371 PlaylistList::iterator x;
3374 /* its not supposed to be visible */
3379 Glib::Mutex::Lock lm (playlist_lock);
3383 unused_playlists.insert (pl);
3385 if ((x = playlists.find (pl)) != playlists.end()) {
3386 playlists.erase (x);
3392 playlists.insert (pl);
3394 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3395 unused_playlists.erase (x);
3402 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3404 if (_state_of_the_state & Deletion) {
3408 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3415 Glib::Mutex::Lock lm (playlist_lock);
3417 PlaylistList::iterator i;
3419 i = find (playlists.begin(), playlists.end(), playlist);
3420 if (i != playlists.end()) {
3421 playlists.erase (i);
3424 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3425 if (i != unused_playlists.end()) {
3426 unused_playlists.erase (i);
3433 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3437 Session::set_audition (boost::shared_ptr<Region> r)
3439 pending_audition_region = r;
3440 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3441 schedule_butler_transport_work ();
3445 Session::audition_playlist ()
3447 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3448 ev->region.reset ();
3453 Session::non_realtime_set_audition ()
3455 if (!pending_audition_region) {
3456 auditioner->audition_current_playlist ();
3458 auditioner->audition_region (pending_audition_region);
3459 pending_audition_region.reset ();
3461 AuditionActive (true); /* EMIT SIGNAL */
3465 Session::audition_region (boost::shared_ptr<Region> r)
3467 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3473 Session::cancel_audition ()
3475 if (auditioner->active()) {
3476 auditioner->cancel_audition ();
3477 AuditionActive (false); /* EMIT SIGNAL */
3482 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3484 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3488 Session::remove_empty_sounds ()
3490 vector<string> audio_filenames;
3492 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3494 Glib::Mutex::Lock lm (source_lock);
3496 TapeFileMatcher tape_file_matcher;
3498 remove_if (audio_filenames.begin(), audio_filenames.end(),
3499 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3501 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3503 sys::path audio_file_path (_session_dir->sound_path());
3505 audio_file_path /= *i;
3507 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3511 sys::remove (audio_file_path);
3512 const string peakfile = peak_path (audio_file_path.to_string());
3513 sys::remove (peakfile);
3515 catch (const sys::filesystem_error& err)
3517 error << err.what() << endmsg;
3524 Session::is_auditioning () const
3526 /* can be called before we have an auditioner object */
3528 return auditioner->active();
3535 Session::set_all_solo (bool yn)
3537 shared_ptr<RouteList> r = routes.reader ();
3539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3540 if (!(*i)->is_hidden()) {
3541 (*i)->set_solo (yn, this);
3549 Session::set_all_listen (bool yn)
3551 shared_ptr<RouteList> r = routes.reader ();
3553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3554 if (!(*i)->is_hidden()) {
3555 (*i)->set_listen (yn, this);
3563 Session::set_all_mute (bool yn)
3565 shared_ptr<RouteList> r = routes.reader ();
3567 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3568 if (!(*i)->is_hidden()) {
3569 (*i)->set_mute (yn, this);
3577 Session::n_diskstreams () const
3581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3583 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3584 if (!(*i)->hidden()) {
3592 Session::graph_reordered ()
3594 /* don't do this stuff if we are setting up connections
3595 from a set_state() call or creating new tracks.
3598 if (_state_of_the_state & InitialConnecting) {
3602 /* every track/bus asked for this to be handled but it was deferred because
3603 we were connecting. do it now.
3606 request_input_change_handling ();
3610 /* force all diskstreams to update their capture offset values to
3611 reflect any changes in latencies within the graph.
3614 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3616 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3617 (*i)->set_capture_offset ();
3622 Session::record_disenable_all ()
3624 record_enable_change_all (false);
3628 Session::record_enable_all ()
3630 record_enable_change_all (true);
3634 Session::record_enable_change_all (bool yn)
3636 shared_ptr<RouteList> r = routes.reader ();
3638 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3639 boost::shared_ptr<Track> t;
3641 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3642 t->set_record_enable (yn, this);
3646 /* since we don't keep rec-enable state, don't mark session dirty */
3650 Session::add_processor (Processor* processor)
3652 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3657 Session::remove_processor (Processor* processor)
3661 PortInsert* port_insert;
3663 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3664 insert_bitset[port_insert->bit_slot()] = false;
3665 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3666 send_bitset[send->bit_slot()] = false;
3667 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3668 return_bitset[send->bit_slot()] = false;
3675 Session::available_capture_duration ()
3677 float sample_bytes_on_disk = 4.0; // keep gcc happy
3679 switch (config.get_native_file_data_format()) {
3681 sample_bytes_on_disk = 4.0;
3685 sample_bytes_on_disk = 3.0;
3689 sample_bytes_on_disk = 2.0;
3693 /* impossible, but keep some gcc versions happy */
3694 fatal << string_compose (_("programming error: %1"),
3695 X_("illegal native file data format"))
3700 double scale = 4096.0 / sample_bytes_on_disk;
3702 if (_total_free_4k_blocks * scale > (double) max_frames) {
3706 return (nframes_t) floor (_total_free_4k_blocks * scale);
3710 Session::add_bundle (shared_ptr<Bundle> bundle)
3713 RCUWriter<BundleList> writer (_bundles);
3714 boost::shared_ptr<BundleList> b = writer.get_copy ();
3715 b->push_back (bundle);
3718 BundleAdded (bundle); /* EMIT SIGNAL */
3724 Session::remove_bundle (shared_ptr<Bundle> bundle)
3726 bool removed = false;
3729 RCUWriter<BundleList> writer (_bundles);
3730 boost::shared_ptr<BundleList> b = writer.get_copy ();
3731 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3733 if (i != b->end()) {
3740 BundleRemoved (bundle); /* EMIT SIGNAL */
3747 Session::bundle_by_name (string name) const
3749 boost::shared_ptr<BundleList> b = _bundles.reader ();
3751 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3752 if ((*i)->name() == name) {
3757 return boost::shared_ptr<Bundle> ();
3761 Session::tempo_map_changed (Change ignored)
3765 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3766 (*i)->update_after_tempo_map_change ();
3769 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3770 (*i)->update_after_tempo_map_change ();
3776 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3777 * the given count with the current block size.
3780 Session::ensure_buffers (ChanCount howmany)
3782 if (current_block_size == 0) {
3783 return; // too early? (is this ok?)
3786 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3787 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3788 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3789 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3790 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3793 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3797 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3799 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3800 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3805 Session::next_insert_id ()
3807 /* this doesn't really loop forever. just think about it */
3810 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3811 if (!insert_bitset[n]) {
3812 insert_bitset[n] = true;
3818 /* none available, so resize and try again */
3820 insert_bitset.resize (insert_bitset.size() + 16, false);
3825 Session::next_send_id ()
3827 /* this doesn't really loop forever. just think about it */
3830 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3831 if (!send_bitset[n]) {
3832 send_bitset[n] = true;
3838 /* none available, so resize and try again */
3840 send_bitset.resize (send_bitset.size() + 16, false);
3845 Session::next_return_id ()
3847 /* this doesn't really loop forever. just think about it */
3850 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3851 if (!return_bitset[n]) {
3852 return_bitset[n] = true;
3858 /* none available, so resize and try again */
3860 return_bitset.resize (return_bitset.size() + 16, false);
3865 Session::mark_send_id (uint32_t id)
3867 if (id >= send_bitset.size()) {
3868 send_bitset.resize (id+16, false);
3870 if (send_bitset[id]) {
3871 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3873 send_bitset[id] = true;
3877 Session::mark_return_id (uint32_t id)
3879 if (id >= return_bitset.size()) {
3880 return_bitset.resize (id+16, false);
3882 if (return_bitset[id]) {
3883 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3885 return_bitset[id] = true;
3889 Session::mark_insert_id (uint32_t id)
3891 if (id >= insert_bitset.size()) {
3892 insert_bitset.resize (id+16, false);
3894 if (insert_bitset[id]) {
3895 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3897 insert_bitset[id] = true;
3900 /* Named Selection management */
3903 Session::named_selection_by_name (string name)
3905 Glib::Mutex::Lock lm (named_selection_lock);
3906 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3907 if ((*i)->name == name) {
3915 Session::add_named_selection (NamedSelection* named_selection)
3918 Glib::Mutex::Lock lm (named_selection_lock);
3919 named_selections.insert (named_selections.begin(), named_selection);
3922 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3928 NamedSelectionAdded (); /* EMIT SIGNAL */
3932 Session::remove_named_selection (NamedSelection* named_selection)
3934 bool removed = false;
3937 Glib::Mutex::Lock lm (named_selection_lock);
3939 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3941 if (i != named_selections.end()) {
3943 named_selections.erase (i);
3950 NamedSelectionRemoved (); /* EMIT SIGNAL */
3955 Session::reset_native_file_format ()
3957 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3959 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3960 (*i)->reset_write_sources (false);
3965 Session::route_name_unique (string n) const
3967 shared_ptr<RouteList> r = routes.reader ();
3969 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3970 if ((*i)->name() == n) {
3979 Session::route_name_internal (string n) const
3981 if (auditioner && auditioner->name() == n) {
3985 if (_click_io && _click_io->name() == n) {
3993 Session::n_playlists () const
3995 Glib::Mutex::Lock lm (playlist_lock);
3996 return playlists.size();
4000 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4002 if (!force && howmany <= _npan_buffers) {
4006 if (_pan_automation_buffer) {
4008 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4009 delete [] _pan_automation_buffer[i];
4012 delete [] _pan_automation_buffer;
4015 _pan_automation_buffer = new pan_t*[howmany];
4017 for (uint32_t i = 0; i < howmany; ++i) {
4018 _pan_automation_buffer[i] = new pan_t[nframes];
4021 _npan_buffers = howmany;
4025 Session::freeze (InterThreadInfo& itt)
4027 shared_ptr<RouteList> r = routes.reader ();
4029 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4031 boost::shared_ptr<Track> t;
4033 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4034 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4044 boost::shared_ptr<Region>
4045 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4046 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4047 InterThreadInfo& itt, bool enable_processing)
4049 boost::shared_ptr<Region> result;
4050 boost::shared_ptr<Playlist> playlist;
4051 boost::shared_ptr<AudioFileSource> fsource;
4053 char buf[PATH_MAX+1];
4054 ChanCount nchans(track.audio_diskstream()->n_channels());
4056 nframes_t this_chunk;
4059 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4060 const string sound_dir = sdir.sound_path().to_string();
4061 nframes_t len = end - start;
4064 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4065 end, start) << endmsg;
4069 // any bigger than this seems to cause stack overflows in called functions
4070 const nframes_t chunk_size = (128 * 1024)/4;
4072 // block all process callback handling
4074 block_processing ();
4076 /* call tree *MUST* hold route_lock */
4078 if ((playlist = track.diskstream()->playlist()) == 0) {
4082 /* external redirects will be a problem */
4084 if (track.has_external_redirects()) {
4088 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4090 for (x = 0; x < 99999; ++x) {
4091 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4092 if (access (buf, F_OK) != 0) {
4098 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4103 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4104 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4107 catch (failed_constructor& err) {
4108 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4112 srcs.push_back (fsource);
4115 /* XXX need to flush all redirects */
4120 /* create a set of reasonably-sized buffers */
4121 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4122 buffers.set_count(nchans);
4124 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4125 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4127 afs->prepare_for_peakfile_writes ();
4130 while (to_do && !itt.cancel) {
4132 this_chunk = min (to_do, chunk_size);
4134 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4139 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4140 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4143 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4149 start += this_chunk;
4150 to_do -= this_chunk;
4152 itt.progress = (float) (1.0 - ((double) to_do / len));
4161 xnow = localtime (&now);
4163 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4164 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4167 afs->update_header (position, *xnow, now);
4168 afs->flush_header ();
4172 /* construct a region to represent the bounced material */
4174 result = RegionFactory::create (srcs, 0,
4175 srcs.front()->length(srcs.front()->timeline_position()),
4176 region_name_from_path (srcs.front()->name(), true));
4181 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4182 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4185 afs->mark_for_remove ();
4188 (*src)->drop_references ();
4192 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4193 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4196 afs->done_with_peakfile_writes ();
4200 unblock_processing ();
4206 Session::get_silent_buffers (ChanCount count)
4208 assert(_silent_buffers->available() >= count);
4209 _silent_buffers->set_count(count);
4211 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4212 for (size_t i= 0; i < count.get(*t); ++i) {
4213 _silent_buffers->get(*t, i).clear();
4217 return *_silent_buffers;
4221 Session::get_scratch_buffers (ChanCount count)
4223 if (count != ChanCount::ZERO) {
4224 assert(_scratch_buffers->available() >= count);
4225 _scratch_buffers->set_count(count);
4227 _scratch_buffers->set_count (_scratch_buffers->available());
4230 return *_scratch_buffers;
4234 Session::get_mix_buffers (ChanCount count)
4236 assert(_mix_buffers->available() >= count);
4237 _mix_buffers->set_count(count);
4238 return *_mix_buffers;
4242 Session::ntracks () const
4245 shared_ptr<RouteList> r = routes.reader ();
4247 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4248 if (boost::dynamic_pointer_cast<Track> (*i)) {
4257 Session::nbusses () const
4260 shared_ptr<RouteList> r = routes.reader ();
4262 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4263 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4272 Session::add_automation_list(AutomationList *al)
4274 automation_lists[al->id()] = al;
4278 Session::compute_initial_length ()
4280 return _engine.frame_rate() * 60 * 5;
4284 Session::sync_order_keys (const char* base)
4286 if (!Config->get_sync_all_route_ordering()) {
4287 /* leave order keys as they are */
4291 boost::shared_ptr<RouteList> r = routes.reader ();
4293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4294 (*i)->sync_order_keys (base);
4297 Route::SyncOrderKeys (base); // EMIT SIGNAL
4301 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4303 Session::have_rec_enabled_diskstream () const
4305 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4308 /** Update the state of our rec-enabled diskstreams flag */
4310 Session::update_have_rec_enabled_diskstream ()
4312 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4313 DiskstreamList::iterator i = dsl->begin ();
4314 while (i != dsl->end () && (*i)->record_enabled () == false) {
4318 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4320 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4322 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4323 RecordStateChanged (); /* EMIT SIGNAL */
4328 Session::listen_position_changed ()
4332 switch (Config->get_listen_position()) {
4333 case AfterFaderListen:
4337 case PreFaderListen:
4342 boost::shared_ptr<RouteList> r = routes.reader ();
4344 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4345 (*i)->put_control_outs_at (p);
4350 Session::solo_control_mode_changed ()
4352 /* cancel all solo or all listen when solo control mode changes */
4354 if (Config->get_solo_control_is_listen_control()) {
4355 set_all_solo (false);
4357 set_all_listen (false);
4362 Session::route_group_changed ()
4364 RouteGroupChanged (); /* EMIT SIGNAL */