2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/filename_extensions.h"
65 #include "ardour/io_processor.h"
66 #include "ardour/midi_diskstream.h"
67 #include "ardour/midi_playlist.h"
68 #include "ardour/midi_region.h"
69 #include "ardour/midi_track.h"
70 #include "ardour/named_selection.h"
71 #include "ardour/playlist.h"
72 #include "ardour/plugin_insert.h"
73 #include "ardour/port_insert.h"
74 #include "ardour/processor.h"
75 #include "ardour/recent_sessions.h"
76 #include "ardour/region_factory.h"
77 #include "ardour/return.h"
78 #include "ardour/route_group.h"
79 #include "ardour/send.h"
80 #include "ardour/session.h"
81 #include "ardour/session_directory.h"
82 #include "ardour/session_directory.h"
83 #include "ardour/session_metadata.h"
84 #include "ardour/slave.h"
85 #include "ardour/smf_source.h"
86 #include "ardour/source_factory.h"
87 #include "ardour/tape_file_matcher.h"
88 #include "ardour/tempo.h"
89 #include "ardour/utils.h"
94 using namespace ARDOUR;
96 using boost::shared_ptr;
98 bool Session::_disable_all_loaded_plugins = false;
100 sigc::signal<void,std::string> Session::Dialog;
101 sigc::signal<int> Session::AskAboutPendingState;
102 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
103 sigc::signal<void> Session::SendFeedback;
105 sigc::signal<void> Session::SMPTEOffsetChanged;
106 sigc::signal<void> Session::StartTimeChanged;
107 sigc::signal<void> Session::EndTimeChanged;
108 sigc::signal<void> Session::AutoBindingOn;
109 sigc::signal<void> Session::AutoBindingOff;
110 sigc::signal<void, std::string, std::string> Session::Exported;
112 Session::Session (AudioEngine &eng,
113 const string& fullpath,
114 const string& snapshot_name,
118 _target_transport_speed (0.0),
119 _requested_return_frame (-1),
120 _scratch_buffers(new BufferSet()),
121 _silent_buffers(new BufferSet()),
122 _mix_buffers(new BufferSet()),
124 _mmc_port (default_mmc_port),
125 _mtc_port (default_mtc_port),
126 _midi_port (default_midi_port),
127 _midi_clock_port (default_midi_clock_port),
128 _session_dir (new SessionDirectory(fullpath)),
129 pending_events (2048),
131 butler_mixdown_buffer (0),
132 butler_gain_buffer (0),
133 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 midi_thread (pthread_t (0)),
136 midi_requests (128), // the size of this should match the midi request pool size
137 diskstreams (new DiskstreamList),
138 routes (new RouteList),
139 _total_free_4k_blocks (0),
140 _bundles (new BundleList),
141 _bundle_xml_node (0),
144 click_emphasis_data (0),
146 _metadata (new SessionMetadata()),
147 _have_rec_enabled_diskstream (false)
152 interpolation.add_channel_to (0, 0);
154 if (!eng.connected()) {
155 throw failed_constructor();
158 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
160 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
161 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
163 first_stage_init (fullpath, snapshot_name);
165 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168 if (create (new_session, mix_template, compute_initial_length())) {
170 throw failed_constructor ();
174 if (second_stage_init (new_session)) {
176 throw failed_constructor ();
179 store_recent_sessions(_name, _path);
181 bool was_dirty = dirty();
183 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
185 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
186 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
189 DirtyChanged (); /* EMIT SIGNAL */
193 Session::Session (AudioEngine &eng,
195 string snapshot_name,
196 AutoConnectOption input_ac,
197 AutoConnectOption output_ac,
198 uint32_t control_out_channels,
199 uint32_t master_out_channels,
200 uint32_t requested_physical_in,
201 uint32_t requested_physical_out,
202 nframes_t initial_length)
205 _target_transport_speed (0.0),
206 _requested_return_frame (-1),
207 _scratch_buffers(new BufferSet()),
208 _silent_buffers(new BufferSet()),
209 _mix_buffers(new BufferSet()),
211 _mmc_port (default_mmc_port),
212 _mtc_port (default_mtc_port),
213 _midi_port (default_midi_port),
214 _midi_clock_port (default_midi_clock_port),
215 _session_dir ( new SessionDirectory(fullpath)),
216 pending_events (2048),
218 butler_mixdown_buffer (0),
219 butler_gain_buffer (0),
220 post_transport_work((PostTransportWork)0),
221 _send_smpte_update (false),
222 midi_thread (pthread_t (0)),
224 diskstreams (new DiskstreamList),
225 routes (new RouteList),
226 _total_free_4k_blocks (0),
227 _bundles (new BundleList),
228 _bundle_xml_node (0),
229 _click_io ((IO *) 0),
231 click_emphasis_data (0),
233 _metadata (new SessionMetadata()),
234 _have_rec_enabled_diskstream (false)
238 interpolation.add_channel_to (0, 0);
240 if (!eng.connected()) {
241 throw failed_constructor();
244 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
246 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
247 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
249 if (n_physical_inputs) {
250 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
253 if (n_physical_outputs) {
254 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
257 first_stage_init (fullpath, snapshot_name);
259 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
262 if (create (new_session, string(), initial_length)) {
264 throw failed_constructor ();
269 /* set up Master Out and Control Out if necessary */
274 if (master_out_channels) {
275 ChanCount count(DataType::AUDIO, master_out_channels);
276 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
277 r->input()->ensure_io (count, false, this);
278 r->output()->ensure_io (count, false, this);
279 r->set_remote_control_id (control_id);
283 /* prohibit auto-connect to master, because there isn't one */
284 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
287 if (control_out_channels) {
288 ChanCount count(DataType::AUDIO, control_out_channels);
289 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
290 r->input()->ensure_io (count, false, this);
291 r->output()->ensure_io (count, false, this);
292 r->set_remote_control_id (control_id++);
298 add_routes (rl, false);
303 if (no_auto_connect()) {
304 input_ac = AutoConnectOption (0);
305 output_ac = AutoConnectOption (0);
308 Config->set_input_auto_connect (input_ac);
309 Config->set_output_auto_connect (output_ac);
311 if (second_stage_init (new_session)) {
313 throw failed_constructor ();
316 store_recent_sessions (_name, _path);
318 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
320 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
331 /* if we got to here, leaving pending capture state around
335 remove_pending_capture_state ();
337 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
339 _engine.remove_session ();
341 GoingAway (); /* EMIT SIGNAL */
347 /* clear history so that no references to objects are held any more */
351 /* clear state tree so that no references to objects are held any more */
355 terminate_butler_thread ();
356 //terminate_midi_thread ();
358 if (click_data != default_click) {
359 delete [] click_data;
362 if (click_emphasis_data != default_click_emphasis) {
363 delete [] click_emphasis_data;
368 delete _scratch_buffers;
369 delete _silent_buffers;
372 AudioDiskstream::free_working_buffers();
374 Route::SyncOrderKeys.clear();
376 #undef TRACK_DESTRUCTION
377 #ifdef TRACK_DESTRUCTION
378 cerr << "delete named selections\n";
379 #endif /* TRACK_DESTRUCTION */
380 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
381 NamedSelectionList::iterator tmp;
390 #ifdef TRACK_DESTRUCTION
391 cerr << "delete playlists\n";
392 #endif /* TRACK_DESTRUCTION */
393 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
394 PlaylistList::iterator tmp;
399 (*i)->drop_references ();
404 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
405 PlaylistList::iterator tmp;
410 (*i)->drop_references ();
416 unused_playlists.clear ();
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete regions\n";
420 #endif /* TRACK_DESTRUCTION */
422 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
423 RegionList::iterator tmp;
428 i->second->drop_references ();
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete routes\n";
437 #endif /* TRACK_DESTRUCTION */
439 RCUWriter<RouteList> writer (routes);
440 boost::shared_ptr<RouteList> r = writer.get_copy ();
441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
442 (*i)->drop_references ();
445 /* writer goes out of scope and updates master */
450 #ifdef TRACK_DESTRUCTION
451 cerr << "delete diskstreams\n";
452 #endif /* TRACK_DESTRUCTION */
454 RCUWriter<DiskstreamList> dwriter (diskstreams);
455 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
456 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
457 (*i)->drop_references ();
461 diskstreams.flush ();
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete audio sources\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
467 SourceMap::iterator tmp;
472 i->second->drop_references ();
479 #ifdef TRACK_DESTRUCTION
480 cerr << "delete route groups\n";
481 #endif /* TRACK_DESTRUCTION */
482 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
486 delete [] butler_mixdown_buffer;
487 delete [] butler_gain_buffer;
489 Crossfade::set_buffer_size (0);
495 Session::set_worst_io_latencies ()
497 _worst_output_latency = 0;
498 _worst_input_latency = 0;
500 if (!_engine.connected()) {
504 boost::shared_ptr<RouteList> r = routes.reader ();
506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
507 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
508 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
513 Session::when_engine_running ()
515 string first_physical_output;
517 BootMessage (_("Set block size and sample rate"));
519 set_block_size (_engine.frames_per_cycle());
520 set_frame_rate (_engine.frame_rate());
522 BootMessage (_("Using configuration"));
524 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
526 /* every time we reconnect, recompute worst case output latencies */
528 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
530 if (synced_to_jack()) {
531 _engine.transport_stop ();
534 if (config.get_jack_time_master()) {
535 _engine.transport_locate (_transport_frame);
543 _click_io.reset (new ClickIO (*this, "click"));
545 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
547 /* existing state for Click */
549 if (_click_io->set_state (*child->children().front()) == 0) {
551 _clicking = Config->get_clicking ();
555 error << _("could not setup Click I/O") << endmsg;
561 /* default state for Click: dual-mono to first 2 physical outputs */
563 for (int physport = 0; physport < 2; ++physport) {
564 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
566 if (physical_output.length()) {
567 if (_click_io->add_port (physical_output, this)) {
568 // relax, even though its an error
573 if (_click_io->n_ports () > ChanCount::ZERO) {
574 _clicking = Config->get_clicking ();
579 catch (failed_constructor& err) {
580 error << _("cannot setup Click I/O") << endmsg;
583 BootMessage (_("Compute I/O Latencies"));
585 set_worst_io_latencies ();
588 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
591 BootMessage (_("Set up standard connections"));
593 /* Create a set of Bundle objects that map
594 to the physical I/O currently available. We create both
595 mono and stereo bundles, so that the common cases of mono
596 and stereo tracks get bundles to put in their mixer strip
597 in / out menus. There may be a nicer way of achieving that;
598 it doesn't really scale that well to higher channel counts
601 /* mono output bundles */
603 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
605 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
607 shared_ptr<Bundle> c (new Bundle (buf, true));
608 c->add_channel (_("mono"));
609 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
614 /* stereo output bundles */
616 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
617 if (np + 1 < n_physical_outputs) {
619 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
620 shared_ptr<Bundle> c (new Bundle (buf, true));
621 c->add_channel (_("L"));
622 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 c->add_channel (_("R"));
624 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
630 /* mono input bundles */
632 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
634 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
636 shared_ptr<Bundle> c (new Bundle (buf, false));
637 c->add_channel (_("mono"));
638 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
643 /* stereo input bundles */
645 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
646 if (np + 1 < n_physical_inputs) {
648 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
650 shared_ptr<Bundle> c (new Bundle (buf, false));
651 c->add_channel (_("L"));
652 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
653 c->add_channel (_("R"));
654 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
660 BootMessage (_("Setup signal flow and plugins"));
664 if (!no_auto_connect()) {
666 if (_master_out && Config->get_auto_connect_standard_busses()) {
668 /* if requested auto-connect the outputs to the first N physical ports.
671 uint32_t limit = _master_out->n_outputs().n_total();
673 for (uint32_t n = 0; n < limit; ++n) {
674 Port* p = _master_out->output()->nth (n);
675 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
677 if (!connect_to.empty()) {
678 if (_master_out->output()->connect (p, connect_to, this)) {
679 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
689 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
690 are undefined, at best.
693 /* control out listens to master bus (but ignores it
694 under some conditions)
697 uint32_t limit = _control_out->n_inputs().n_audio();
700 for (uint32_t n = 0; n < limit; ++n) {
701 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
702 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
705 string connect_to = o->name();
706 if (_control_out->input()->connect (p, connect_to, this)) {
707 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
715 /* if control out is not connected,
716 connect control out to physical outs, but use ones after the master if possible
719 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
721 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
723 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
726 _control_out->output()->connect_ports_to_bundle (b, this);
728 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
729 Config->get_monitor_bus_preferred_bundle())
735 /* XXX this logic is wrong for mixed port types */
737 uint32_t shift = _master_out->n_outputs().n_audio();
738 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
739 limit = _control_out->n_outputs().n_audio();
741 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
743 for (uint32_t n = 0; n < limit; ++n) {
745 Port* p = _control_out->output()->nth (n);
746 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
748 if (!connect_to.empty()) {
749 if (_control_out->output()->connect (p, connect_to, this)) {
750 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
761 /* catch up on send+insert cnts */
763 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
765 /* hook us up to the engine */
767 BootMessage (_("Connect to engine"));
769 _engine.set_session (this);
773 Session::hookup_io ()
775 /* stop graph reordering notifications from
776 causing resorts, etc.
779 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
784 /* we delay creating the auditioner till now because
785 it makes its own connections to ports.
786 the engine has to be running for this to work.
790 auditioner.reset (new Auditioner (*this));
793 catch (failed_constructor& err) {
794 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
798 /* load bundles, which we may have postponed earlier on */
799 if (_bundle_xml_node) {
800 load_bundles (*_bundle_xml_node);
801 delete _bundle_xml_node;
804 /* Tell all IO objects to connect themselves together */
806 IO::enable_connecting ();
808 /* Now reset all panners */
810 Delivery::reset_panners ();
812 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
816 boost::shared_ptr<RouteList> r = routes.reader ();
818 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
820 if ((*x)->is_control() || (*x)->is_master()) {
824 (*x)->listen_via (_control_out,
825 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
830 /* Anyone who cares about input state, wake up and do something */
832 IOConnectionsComplete (); /* EMIT SIGNAL */
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
836 /* now handle the whole enchilada as if it was one
842 /* update the full solo state, which can't be
843 correctly determined on a per-route basis, but
844 needs the global overview that only the session
848 update_route_solo_state ();
852 Session::playlist_length_changed ()
854 /* we can't just increase end_location->end() if pl->get_maximum_extent()
855 if larger. if the playlist used to be the longest playlist,
856 and its now shorter, we have to decrease end_location->end(). hence,
857 we have to iterate over all diskstreams and check the
858 playlists currently in use.
864 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
866 boost::shared_ptr<Playlist> playlist;
868 if ((playlist = dstream->playlist()) != 0) {
869 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
872 /* see comment in playlist_length_changed () */
877 Session::record_enabling_legal () const
879 /* this used to be in here, but survey says.... we don't need to restrict it */
880 // if (record_status() == Recording) {
884 if (Config->get_all_safe()) {
891 Session::reset_input_monitor_state ()
893 if (transport_rolling()) {
895 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
897 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
898 if ((*i)->record_enabled ()) {
899 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
900 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
904 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
906 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
907 if ((*i)->record_enabled ()) {
908 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
909 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
916 Session::auto_punch_start_changed (Location* location)
918 replace_event (Event::PunchIn, location->start());
920 if (get_record_enabled() && config.get_punch_in()) {
921 /* capture start has been changed, so save new pending state */
922 save_state ("", true);
927 Session::auto_punch_end_changed (Location* location)
929 nframes_t when_to_stop = location->end();
930 // when_to_stop += _worst_output_latency + _worst_input_latency;
931 replace_event (Event::PunchOut, when_to_stop);
935 Session::auto_punch_changed (Location* location)
937 nframes_t when_to_stop = location->end();
939 replace_event (Event::PunchIn, location->start());
940 //when_to_stop += _worst_output_latency + _worst_input_latency;
941 replace_event (Event::PunchOut, when_to_stop);
945 Session::auto_loop_changed (Location* location)
947 replace_event (Event::AutoLoop, location->end(), location->start());
949 if (transport_rolling() && play_loop) {
951 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
953 if (_transport_frame > location->end()) {
954 // relocate to beginning of loop
955 clear_events (Event::LocateRoll);
957 request_locate (location->start(), true);
960 else if (Config->get_seamless_loop() && !loop_changing) {
962 // schedule a locate-roll to refill the diskstreams at the
964 loop_changing = true;
966 if (location->end() > last_loopend) {
967 clear_events (Event::LocateRoll);
968 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
975 last_loopend = location->end();
979 Session::set_auto_punch_location (Location* location)
983 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
984 auto_punch_start_changed_connection.disconnect();
985 auto_punch_end_changed_connection.disconnect();
986 auto_punch_changed_connection.disconnect();
987 existing->set_auto_punch (false, this);
988 remove_event (existing->start(), Event::PunchIn);
989 clear_events (Event::PunchOut);
990 auto_punch_location_changed (0);
999 if (location->end() <= location->start()) {
1000 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1004 auto_punch_start_changed_connection.disconnect();
1005 auto_punch_end_changed_connection.disconnect();
1006 auto_punch_changed_connection.disconnect();
1008 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1009 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1010 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1012 location->set_auto_punch (true, this);
1015 auto_punch_changed (location);
1017 auto_punch_location_changed (location);
1021 Session::set_auto_loop_location (Location* location)
1025 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1026 auto_loop_start_changed_connection.disconnect();
1027 auto_loop_end_changed_connection.disconnect();
1028 auto_loop_changed_connection.disconnect();
1029 existing->set_auto_loop (false, this);
1030 remove_event (existing->end(), Event::AutoLoop);
1031 auto_loop_location_changed (0);
1036 if (location == 0) {
1040 if (location->end() <= location->start()) {
1041 error << _("Session: you can't use a mark for auto loop") << endmsg;
1045 last_loopend = location->end();
1047 auto_loop_start_changed_connection.disconnect();
1048 auto_loop_end_changed_connection.disconnect();
1049 auto_loop_changed_connection.disconnect();
1051 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1052 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1053 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1055 location->set_auto_loop (true, this);
1057 /* take care of our stuff first */
1059 auto_loop_changed (location);
1061 /* now tell everyone else */
1063 auto_loop_location_changed (location);
1067 Session::locations_added (Location* ignored)
1073 Session::locations_changed ()
1075 _locations.apply (*this, &Session::handle_locations_changed);
1079 Session::handle_locations_changed (Locations::LocationList& locations)
1081 Locations::LocationList::iterator i;
1083 bool set_loop = false;
1084 bool set_punch = false;
1086 for (i = locations.begin(); i != locations.end(); ++i) {
1090 if (location->is_auto_punch()) {
1091 set_auto_punch_location (location);
1094 if (location->is_auto_loop()) {
1095 set_auto_loop_location (location);
1099 if (location->is_start()) {
1100 start_location = location;
1102 if (location->is_end()) {
1103 end_location = location;
1108 set_auto_loop_location (0);
1111 set_auto_punch_location (0);
1118 Session::enable_record ()
1120 /* XXX really atomic compare+swap here */
1121 if (g_atomic_int_get (&_record_status) != Recording) {
1122 g_atomic_int_set (&_record_status, Recording);
1123 _last_record_location = _transport_frame;
1124 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1126 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1127 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1128 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1129 if ((*i)->record_enabled ()) {
1130 (*i)->monitor_input (true);
1135 RecordStateChanged ();
1140 Session::disable_record (bool rt_context, bool force)
1144 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1146 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1147 g_atomic_int_set (&_record_status, Disabled);
1149 if (rs == Recording) {
1150 g_atomic_int_set (&_record_status, Enabled);
1154 // FIXME: timestamp correct? [DR]
1155 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1156 // does this /need/ to be sent in all cases?
1158 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1160 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1161 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1163 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1164 if ((*i)->record_enabled ()) {
1165 (*i)->monitor_input (false);
1170 RecordStateChanged (); /* emit signal */
1173 remove_pending_capture_state ();
1179 Session::step_back_from_record ()
1181 /* XXX really atomic compare+swap here */
1182 if (g_atomic_int_get (&_record_status) == Recording) {
1183 g_atomic_int_set (&_record_status, Enabled);
1185 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1186 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1188 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1189 if ((*i)->record_enabled ()) {
1190 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1191 (*i)->monitor_input (false);
1199 Session::maybe_enable_record ()
1201 g_atomic_int_set (&_record_status, Enabled);
1203 /* this function is currently called from somewhere other than an RT thread.
1204 this save_state() call therefore doesn't impact anything.
1207 save_state ("", true);
1209 if (_transport_speed) {
1210 if (!config.get_punch_in()) {
1214 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1215 RecordStateChanged (); /* EMIT SIGNAL */
1222 Session::audible_frame () const
1228 /* the first of these two possible settings for "offset"
1229 mean that the audible frame is stationary until
1230 audio emerges from the latency compensation
1233 the second means that the audible frame is stationary
1234 until audio would emerge from a physical port
1235 in the absence of any plugin latency compensation
1238 offset = _worst_output_latency;
1240 if (offset > current_block_size) {
1241 offset -= current_block_size;
1243 /* XXX is this correct? if we have no external
1244 physical connections and everything is internal
1245 then surely this is zero? still, how
1246 likely is that anyway?
1248 offset = current_block_size;
1251 if (synced_to_jack()) {
1252 tf = _engine.transport_frame();
1254 tf = _transport_frame;
1259 if (!non_realtime_work_pending()) {
1263 /* check to see if we have passed the first guaranteed
1264 audible frame past our last start position. if not,
1265 return that last start point because in terms
1266 of audible frames, we have not moved yet.
1269 if (_transport_speed > 0.0f) {
1271 if (!play_loop || !have_looped) {
1272 if (tf < _last_roll_location + offset) {
1273 return _last_roll_location;
1281 } else if (_transport_speed < 0.0f) {
1283 /* XXX wot? no backward looping? */
1285 if (tf > _last_roll_location - offset) {
1286 return _last_roll_location;
1298 Session::set_frame_rate (nframes_t frames_per_second)
1300 /** \fn void Session::set_frame_size(nframes_t)
1301 the AudioEngine object that calls this guarantees
1302 that it will not be called while we are also in
1303 ::process(). Its fine to do things that block
1307 _base_frame_rate = frames_per_second;
1311 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1315 // XXX we need some equivalent to this, somehow
1316 // SndFileSource::setup_standard_crossfades (frames_per_second);
1320 /* XXX need to reset/reinstantiate all LADSPA plugins */
1324 Session::set_block_size (nframes_t nframes)
1326 /* the AudioEngine guarantees
1327 that it will not be called while we are also in
1328 ::process(). It is therefore fine to do things that block
1333 current_block_size = nframes;
1335 ensure_buffers(_scratch_buffers->available());
1337 delete [] _gain_automation_buffer;
1338 _gain_automation_buffer = new gain_t[nframes];
1340 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1342 boost::shared_ptr<RouteList> r = routes.reader ();
1344 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1345 (*i)->set_block_size (nframes);
1348 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1349 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1350 (*i)->set_block_size (nframes);
1353 set_worst_io_latencies ();
1358 Session::set_default_fade (float steepness, float fade_msecs)
1361 nframes_t fade_frames;
1363 /* Don't allow fade of less 1 frame */
1365 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1372 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1376 default_fade_msecs = fade_msecs;
1377 default_fade_steepness = steepness;
1380 // jlc, WTF is this!
1381 Glib::RWLock::ReaderLock lm (route_lock);
1382 AudioRegion::set_default_fade (steepness, fade_frames);
1387 /* XXX have to do this at some point */
1388 /* foreach region using default fade, reset, then
1389 refill_all_diskstream_buffers ();
1394 struct RouteSorter {
1395 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1396 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1398 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1401 if (r1->fed_by.empty()) {
1402 if (r2->fed_by.empty()) {
1403 /* no ardour-based connections inbound to either route. just use signal order */
1404 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1406 /* r2 has connections, r1 does not; run r1 early */
1410 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1417 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1419 shared_ptr<Route> r2;
1421 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1422 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1426 /* make a copy of the existing list of routes that feed r1 */
1428 set<shared_ptr<Route> > existing = r1->fed_by;
1430 /* for each route that feeds r1, recurse, marking it as feeding
1434 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1437 /* r2 is a route that feeds r1 which somehow feeds base. mark
1438 base as being fed by r2
1441 rbase->fed_by.insert (r2);
1445 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1449 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1453 /* now recurse, so that we can mark base as being fed by
1454 all routes that feed r2
1457 trace_terminal (r2, rbase);
1464 Session::resort_routes ()
1466 /* don't do anything here with signals emitted
1467 by Routes while we are being destroyed.
1470 if (_state_of_the_state & Deletion) {
1477 RCUWriter<RouteList> writer (routes);
1478 shared_ptr<RouteList> r = writer.get_copy ();
1479 resort_routes_using (r);
1480 /* writer goes out of scope and forces update */
1485 Session::resort_routes_using (shared_ptr<RouteList> r)
1487 RouteList::iterator i, j;
1489 for (i = r->begin(); i != r->end(); ++i) {
1491 (*i)->fed_by.clear ();
1493 for (j = r->begin(); j != r->end(); ++j) {
1495 /* although routes can feed themselves, it will
1496 cause an endless recursive descent if we
1497 detect it. so don't bother checking for
1505 if ((*j)->feeds (*i)) {
1506 (*i)->fed_by.insert (*j);
1511 for (i = r->begin(); i != r->end(); ++i) {
1512 trace_terminal (*i, *i);
1519 cerr << "finished route resort\n";
1521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1522 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1529 list<boost::shared_ptr<MidiTrack> >
1530 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1532 char track_name[32];
1533 uint32_t track_id = 0;
1536 RouteList new_routes;
1537 list<boost::shared_ptr<MidiTrack> > ret;
1538 //uint32_t control_id;
1540 // FIXME: need physical I/O and autoconnect stuff for MIDI
1542 /* count existing midi tracks */
1545 shared_ptr<RouteList> r = routes.reader ();
1547 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1548 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1549 if (!(*i)->is_hidden()) {
1551 //channels_used += (*i)->n_inputs().n_midi();
1557 vector<string> physinputs;
1558 vector<string> physoutputs;
1560 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1561 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1563 // control_id = ntracks() + nbusses();
1567 /* check for duplicate route names, since we might have pre-existing
1568 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1569 save, close,restart,add new route - first named route is now
1577 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1579 if (route_by_name (track_name) == 0) {
1583 } while (track_id < (UINT_MAX-1));
1585 shared_ptr<MidiTrack> track;
1588 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1590 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1591 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1596 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1597 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1603 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1607 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1608 port = physinputs[(channels_used+x)%nphysical_in];
1611 if (port.length() && track->connect_input (track->input (x), port, this)) {
1617 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1621 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1622 port = physoutputs[(channels_used+x)%nphysical_out];
1623 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1625 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1629 if (port.length() && track->connect_output (track->output (x), port, this)) {
1634 channels_used += track->n_inputs ().n_midi();
1638 track->midi_diskstream()->non_realtime_input_change();
1639 track->set_route_group (route_group, 0);
1641 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1642 //track->set_remote_control_id (control_id);
1644 new_routes.push_back (track);
1645 ret.push_back (track);
1648 catch (failed_constructor &err) {
1649 error << _("Session: could not create new midi track.") << endmsg;
1652 /* we need to get rid of this, since the track failed to be created */
1653 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1656 RCUWriter<DiskstreamList> writer (diskstreams);
1657 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1658 ds->remove (track->midi_diskstream());
1665 catch (AudioEngine::PortRegistrationFailure& pfe) {
1667 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;
1670 /* we need to get rid of this, since the track failed to be created */
1671 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1674 RCUWriter<DiskstreamList> writer (diskstreams);
1675 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1676 ds->remove (track->midi_diskstream());
1687 if (!new_routes.empty()) {
1688 add_routes (new_routes, false);
1689 save_state (_current_snapshot_name);
1695 list<boost::shared_ptr<AudioTrack> >
1696 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1698 char track_name[32];
1699 uint32_t track_id = 0;
1701 uint32_t channels_used = 0;
1703 RouteList new_routes;
1704 list<boost::shared_ptr<AudioTrack> > ret;
1705 uint32_t control_id;
1707 /* count existing audio tracks */
1710 shared_ptr<RouteList> r = routes.reader ();
1712 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1713 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1714 if (!(*i)->is_hidden()) {
1716 channels_used += (*i)->n_inputs().n_audio();
1722 vector<string> physinputs;
1723 vector<string> physoutputs;
1725 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1726 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1728 control_id = ntracks() + nbusses() + 1;
1732 /* check for duplicate route names, since we might have pre-existing
1733 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1734 save, close,restart,add new route - first named route is now
1742 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1744 if (route_by_name (track_name) == 0) {
1748 } while (track_id < (UINT_MAX-1));
1750 shared_ptr<AudioTrack> track;
1753 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1755 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1756 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1757 input_channels, output_channels)
1762 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1763 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1764 input_channels, output_channels)
1769 if (!physinputs.empty()) {
1770 uint32_t nphysical_in = physinputs.size();
1772 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1776 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1777 port = physinputs[(channels_used+x)%nphysical_in];
1780 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1786 if (!physoutputs.empty()) {
1787 uint32_t nphysical_out = physoutputs.size();
1789 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1792 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1793 port = physoutputs[(channels_used+x)%nphysical_out];
1794 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1795 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1796 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1800 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1806 channels_used += track->n_inputs ().n_audio();
1808 track->set_route_group (route_group, 0);
1810 track->audio_diskstream()->non_realtime_input_change();
1812 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1813 track->set_remote_control_id (control_id);
1816 new_routes.push_back (track);
1817 ret.push_back (track);
1820 catch (failed_constructor &err) {
1821 error << _("Session: could not create new audio track.") << endmsg;
1824 /* we need to get rid of this, since the track failed to be created */
1825 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1828 RCUWriter<DiskstreamList> writer (diskstreams);
1829 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1830 ds->remove (track->audio_diskstream());
1837 catch (AudioEngine::PortRegistrationFailure& pfe) {
1839 error << pfe.what() << endmsg;
1842 /* we need to get rid of this, since the track failed to be created */
1843 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1846 RCUWriter<DiskstreamList> writer (diskstreams);
1847 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1848 ds->remove (track->audio_diskstream());
1859 if (!new_routes.empty()) {
1860 add_routes (new_routes, true);
1867 Session::set_remote_control_ids ()
1869 RemoteModel m = Config->get_remote_model();
1871 shared_ptr<RouteList> r = routes.reader ();
1873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1874 if ( MixerOrdered == m) {
1875 long order = (*i)->order_key(N_("signal"));
1876 (*i)->set_remote_control_id( order+1 );
1877 } else if ( EditorOrdered == m) {
1878 long order = (*i)->order_key(N_("editor"));
1879 (*i)->set_remote_control_id( order+1 );
1880 } else if ( UserOrdered == m) {
1881 //do nothing ... only changes to remote id's are initiated by user
1888 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1891 uint32_t bus_id = 1;
1893 uint32_t channels_used = 0;
1896 uint32_t control_id;
1898 /* count existing audio busses */
1901 shared_ptr<RouteList> r = routes.reader ();
1903 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1904 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1906 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1909 channels_used += (*i)->n_inputs().n_audio();
1915 vector<string> physinputs;
1916 vector<string> physoutputs;
1918 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1919 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1921 n_physical_audio_outputs = physoutputs.size();
1922 n_physical_audio_inputs = physinputs.size();
1924 control_id = ntracks() + nbusses() + 1;
1929 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1933 if (route_by_name (bus_name) == 0) {
1937 } while (bus_id < (UINT_MAX-1));
1940 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1942 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1943 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1944 input_channels, output_channels)
1950 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1951 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1952 input_channels, output_channels)
1957 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1960 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1961 port = physinputs[((n+x)%n_physical_audio_inputs)];
1964 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1969 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1972 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1973 port = physoutputs[((n+x)%n_physical_outputs)];
1974 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1976 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1980 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1985 channels_used += bus->n_inputs ().n_audio();
1987 bus->set_route_group (route_group, 0);
1988 bus->set_remote_control_id (control_id);
1991 ret.push_back (bus);
1995 catch (failed_constructor &err) {
1996 error << _("Session: could not create new audio route.") << endmsg;
2000 catch (AudioEngine::PortRegistrationFailure& pfe) {
2001 error << pfe.what() << endmsg;
2011 add_routes (ret, true);
2019 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2023 uint32_t control_id;
2025 uint32_t number = 1;
2027 if (!tree.read (template_path.c_str())) {
2031 XMLNode* node = tree.root();
2033 control_id = ntracks() + nbusses() + 1;
2037 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2039 std::string node_name = IO::name_from_state (*node_copy.children().front());
2041 /* generate a new name by adding a number to the end of the template name */
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);
2061 Track::zero_diskstream_id_in_xml (node_copy);
2064 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2067 error << _("Session: cannot create track/bus from template description") << endmsg;
2071 if (boost::dynamic_pointer_cast<Track>(route)) {
2072 /* force input/output change signals so that the new diskstream
2073 picks up the configuration of the route. During session
2074 loading this normally happens in a different way.
2076 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2077 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2080 route->set_remote_control_id (control_id);
2083 ret.push_back (route);
2086 catch (failed_constructor &err) {
2087 error << _("Session: could not create new route from template") << endmsg;
2091 catch (AudioEngine::PortRegistrationFailure& pfe) {
2092 error << pfe.what() << endmsg;
2101 add_routes (ret, true);
2108 Session::add_routes (RouteList& new_routes, bool save)
2111 RCUWriter<RouteList> writer (routes);
2112 shared_ptr<RouteList> r = writer.get_copy ();
2113 r->insert (r->end(), new_routes.begin(), new_routes.end());
2116 /* if there is no control out and we're not in the middle of loading,
2117 resort the graph here. if there is a control out, we will resort
2118 toward the end of this method. if we are in the middle of loading,
2119 we will resort when done.
2122 if (!_control_out && IO::connecting_legal) {
2123 resort_routes_using (r);
2127 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2129 boost::weak_ptr<Route> wpr (*x);
2131 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2132 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2133 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2134 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2135 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2136 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2138 if ((*x)->is_master()) {
2142 if ((*x)->is_control()) {
2143 _control_out = (*x);
2147 if (_control_out && IO::connecting_legal) {
2149 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2150 if ((*x)->is_control() || (*x)->is_master()) {
2153 (*x)->listen_via (_control_out,
2154 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2164 save_state (_current_snapshot_name);
2167 RouteAdded (new_routes); /* EMIT SIGNAL */
2171 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2173 boost::shared_ptr<RouteList> r = routes.reader ();
2174 boost::shared_ptr<Send> s;
2178 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2179 if (boost::dynamic_pointer_cast<Track>(*i)) {
2180 if ((s = (*i)->internal_send_for (dest)) != 0) {
2181 s->amp()->gain_control()->set_value (0.0);
2188 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2190 boost::shared_ptr<RouteList> r = routes.reader ();
2191 boost::shared_ptr<Send> s;
2195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2196 if (boost::dynamic_pointer_cast<Track>(*i)) {
2197 if ((s = (*i)->internal_send_for (dest)) != 0) {
2198 s->amp()->gain_control()->set_value (1.0);
2205 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2207 boost::shared_ptr<RouteList> r = routes.reader ();
2208 boost::shared_ptr<Send> s;
2212 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2213 if (boost::dynamic_pointer_cast<Track>(*i)) {
2214 if ((s = (*i)->internal_send_for (dest)) != 0) {
2215 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2222 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2224 boost::shared_ptr<RouteList> r = routes.reader ();
2225 boost::shared_ptr<RouteList> t (new RouteList);
2227 /* only send tracks */
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if (boost::dynamic_pointer_cast<Track>(*i)) {
2235 add_internal_sends (dest, p, t);
2240 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2242 if (dest->is_control() || dest->is_master()) {
2246 if (!dest->internal_return()) {
2247 dest->add_internal_return();
2250 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2252 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2256 (*i)->listen_via (dest, p, true, true);
2261 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2263 /* need to do this in case we're rolling at the time, to prevent false underruns */
2264 dstream->do_refill_with_alloc ();
2266 dstream->set_block_size (current_block_size);
2269 RCUWriter<DiskstreamList> writer (diskstreams);
2270 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2271 ds->push_back (dstream);
2272 /* writer goes out of scope, copies ds back to main */
2275 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2276 /* this will connect to future changes, and check the current length */
2277 diskstream_playlist_changed (dstream);
2279 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2281 dstream->prepare ();
2286 Session::remove_route (shared_ptr<Route> route)
2289 RCUWriter<RouteList> writer (routes);
2290 shared_ptr<RouteList> rs = writer.get_copy ();
2294 /* deleting the master out seems like a dumb
2295 idea, but its more of a UI policy issue
2299 if (route == _master_out) {
2300 _master_out = shared_ptr<Route> ();
2303 if (route == _control_out) {
2305 /* cancel control outs for all routes */
2307 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2308 (*r)->drop_listen (_control_out);
2311 _control_out.reset ();
2314 update_route_solo_state ();
2316 /* writer goes out of scope, forces route list update */
2319 boost::shared_ptr<Track> t;
2320 boost::shared_ptr<Diskstream> ds;
2322 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2323 ds = t->diskstream();
2329 RCUWriter<DiskstreamList> dsl (diskstreams);
2330 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2335 find_current_end ();
2337 // We need to disconnect the routes inputs and outputs
2339 route->input()->disconnect (0);
2340 route->output()->disconnect (0);
2342 update_latency_compensation (false, false);
2345 /* get rid of it from the dead wood collection in the route list manager */
2347 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2351 /* try to cause everyone to drop their references */
2353 route->drop_references ();
2355 sync_order_keys (N_("session"));
2357 /* save the new state of the world */
2359 if (save_state (_current_snapshot_name)) {
2360 save_history (_current_snapshot_name);
2365 Session::route_mute_changed (void* src)
2371 Session::route_listen_changed (void* src, boost::weak_ptr<Route> wpr)
2373 boost::shared_ptr<Route> route = wpr.lock();
2375 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2379 if (route->listening()) {
2381 } else if (_listen_cnt > 0) {
2387 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2389 if (solo_update_disabled) {
2394 boost::shared_ptr<Route> route = wpr.lock ();
2397 /* should not happen */
2398 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2402 shared_ptr<RouteList> r = routes.reader ();
2405 if (route->soloed()) {
2411 /* now mod the solo level of all other routes except master & control outs
2412 so that they will be silent if appropriate.
2415 solo_update_disabled = true;
2416 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2418 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2420 (*i)->mod_solo_level (delta);
2424 /* make sure master is never muted by solo */
2426 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2427 _master_out->mod_solo_level (1);
2430 /* ditto for control outs make sure master is never muted by solo */
2432 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2433 _control_out->mod_solo_level (1);
2436 solo_update_disabled = false;
2437 update_route_solo_state (r);
2438 SoloChanged (); /* EMIT SIGNAL */
2443 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2445 /* now figure out if anything that matters is soloed */
2447 bool something_soloed = false;
2450 r = routes.reader();
2453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2454 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2455 something_soloed = true;
2460 if (something_soloed != _non_soloed_outs_muted) {
2461 _non_soloed_outs_muted = something_soloed;
2462 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2467 Session::route_by_name (string name)
2469 shared_ptr<RouteList> r = routes.reader ();
2471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2472 if ((*i)->name() == name) {
2477 return shared_ptr<Route> ((Route*) 0);
2481 Session::route_by_id (PBD::ID id)
2483 shared_ptr<RouteList> r = routes.reader ();
2485 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2486 if ((*i)->id() == id) {
2491 return shared_ptr<Route> ((Route*) 0);
2495 Session::route_by_remote_id (uint32_t id)
2497 shared_ptr<RouteList> r = routes.reader ();
2499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2500 if ((*i)->remote_control_id() == id) {
2505 return shared_ptr<Route> ((Route*) 0);
2509 Session::find_current_end ()
2511 if (_state_of_the_state & Loading) {
2515 nframes_t max = get_maximum_extent ();
2517 if (max > end_location->end()) {
2518 end_location->set_end (max);
2520 DurationChanged(); /* EMIT SIGNAL */
2525 Session::get_maximum_extent () const
2530 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2532 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2533 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2535 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2536 if ((me = pl->get_maximum_extent()) > max) {
2544 boost::shared_ptr<Diskstream>
2545 Session::diskstream_by_name (string name)
2547 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2549 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2550 if ((*i)->name() == name) {
2555 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2558 boost::shared_ptr<Diskstream>
2559 Session::diskstream_by_id (const PBD::ID& id)
2561 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2564 if ((*i)->id() == id) {
2569 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2572 /* Region management */
2575 Session::new_region_name (string old)
2577 string::size_type last_period;
2579 string::size_type len = old.length() + 64;
2582 if ((last_period = old.find_last_of ('.')) == string::npos) {
2584 /* no period present - add one explicitly */
2587 last_period = old.length() - 1;
2592 number = atoi (old.substr (last_period+1).c_str());
2596 while (number < (UINT_MAX-1)) {
2598 RegionList::const_iterator i;
2603 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2606 for (i = regions.begin(); i != regions.end(); ++i) {
2607 if (i->second->name() == sbuf) {
2612 if (i == regions.end()) {
2617 if (number != (UINT_MAX-1)) {
2621 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2626 Session::region_name (string& result, string base, bool newlevel)
2631 if (base.find("/") != string::npos) {
2632 base = base.substr(base.find_last_of("/") + 1);
2637 Glib::Mutex::Lock lm (region_lock);
2639 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2648 string::size_type pos;
2650 pos = base.find_last_of ('.');
2652 /* pos may be npos, but then we just use entire base */
2654 subbase = base.substr (0, pos);
2659 Glib::Mutex::Lock lm (region_lock);
2661 map<string,uint32_t>::iterator x;
2665 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2667 region_name_map[subbase] = 1;
2670 snprintf (buf, sizeof (buf), ".%d", x->second);
2681 Session::add_region (boost::shared_ptr<Region> region)
2683 vector<boost::shared_ptr<Region> > v;
2684 v.push_back (region);
2689 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2694 Glib::Mutex::Lock lm (region_lock);
2696 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2698 boost::shared_ptr<Region> region = *ii;
2702 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2706 RegionList::iterator x;
2708 for (x = regions.begin(); x != regions.end(); ++x) {
2710 if (region->region_list_equivalent (x->second)) {
2715 if (x == regions.end()) {
2717 pair<RegionList::key_type,RegionList::mapped_type> entry;
2719 entry.first = region->id();
2720 entry.second = region;
2722 pair<RegionList::iterator,bool> x = regions.insert (entry);
2734 /* mark dirty because something has changed even if we didn't
2735 add the region to the region list.
2742 vector<boost::weak_ptr<Region> > v;
2743 boost::shared_ptr<Region> first_r;
2745 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2747 boost::shared_ptr<Region> region = *ii;
2751 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2754 v.push_back (region);
2761 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2762 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2764 update_region_name_map (region);
2768 RegionsAdded (v); /* EMIT SIGNAL */
2774 Session::update_region_name_map (boost::shared_ptr<Region> region)
2776 string::size_type last_period = region->name().find_last_of ('.');
2778 if (last_period != string::npos && last_period < region->name().length() - 1) {
2780 string base = region->name().substr (0, last_period);
2781 string number = region->name().substr (last_period+1);
2782 map<string,uint32_t>::iterator x;
2784 /* note that if there is no number, we get zero from atoi,
2788 region_name_map[base] = atoi (number);
2793 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2795 boost::shared_ptr<Region> region (weak_region.lock ());
2801 if (what_changed & Region::HiddenChanged) {
2802 /* relay hidden changes */
2803 RegionHiddenChange (region);
2806 if (what_changed & NameChanged) {
2807 update_region_name_map (region);
2812 Session::remove_region (boost::weak_ptr<Region> weak_region)
2814 RegionList::iterator i;
2815 boost::shared_ptr<Region> region (weak_region.lock ());
2821 bool removed = false;
2824 Glib::Mutex::Lock lm (region_lock);
2826 if ((i = regions.find (region->id())) != regions.end()) {
2832 /* mark dirty because something has changed even if we didn't
2833 remove the region from the region list.
2839 RegionRemoved(region); /* EMIT SIGNAL */
2843 boost::shared_ptr<Region>
2844 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2846 RegionList::iterator i;
2847 boost::shared_ptr<Region> region;
2849 Glib::Mutex::Lock lm (region_lock);
2851 for (i = regions.begin(); i != regions.end(); ++i) {
2855 if (region->whole_file()) {
2857 if (child->source_equivalent (region)) {
2863 return boost::shared_ptr<Region> ();
2867 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2869 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2870 (*i)->get_region_list_equivalent_regions (region, result);
2874 Session::destroy_region (boost::shared_ptr<Region> region)
2876 vector<boost::shared_ptr<Source> > srcs;
2879 if (region->playlist()) {
2880 region->playlist()->destroy_region (region);
2883 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2884 srcs.push_back (region->source (n));
2888 region->drop_references ();
2890 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2892 (*i)->mark_for_remove ();
2893 (*i)->drop_references ();
2895 cerr << "source was not used by any playlist\n";
2902 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2904 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2905 destroy_region (*i);
2911 Session::remove_last_capture ()
2913 list<boost::shared_ptr<Region> > r;
2915 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2917 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2918 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2921 r.insert (r.end(), l.begin(), l.end());
2926 destroy_regions (r);
2928 save_state (_current_snapshot_name);
2934 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2940 /* Source Management */
2943 Session::add_source (boost::shared_ptr<Source> source)
2945 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2946 pair<SourceMap::iterator,bool> result;
2948 entry.first = source->id();
2949 entry.second = source;
2952 Glib::Mutex::Lock lm (source_lock);
2953 result = sources.insert (entry);
2956 if (result.second) {
2957 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2961 boost::shared_ptr<AudioFileSource> afs;
2963 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2964 if (Config->get_auto_analyse_audio()) {
2965 Analyser::queue_source_for_analysis (source, false);
2971 Session::remove_source (boost::weak_ptr<Source> src)
2973 SourceMap::iterator i;
2974 boost::shared_ptr<Source> source = src.lock();
2981 Glib::Mutex::Lock lm (source_lock);
2983 if ((i = sources.find (source->id())) != sources.end()) {
2988 if (!_state_of_the_state & InCleanup) {
2990 /* save state so we don't end up with a session file
2991 referring to non-existent sources.
2994 save_state (_current_snapshot_name);
2998 boost::shared_ptr<Source>
2999 Session::source_by_id (const PBD::ID& id)
3001 Glib::Mutex::Lock lm (source_lock);
3002 SourceMap::iterator i;
3003 boost::shared_ptr<Source> source;
3005 if ((i = sources.find (id)) != sources.end()) {
3012 boost::shared_ptr<Source>
3013 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3015 Glib::Mutex::Lock lm (source_lock);
3017 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3018 cerr << "comparing " << path << " with " << i->second->name() << endl;
3019 boost::shared_ptr<AudioFileSource> afs
3020 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3022 if (afs && afs->path() == path && chn == afs->channel()) {
3026 return boost::shared_ptr<Source>();
3031 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3034 string old_basename = PBD::basename_nosuffix (oldname);
3035 string new_legalized = legalize_for_path (newname);
3037 /* note: we know (or assume) the old path is already valid */
3041 /* destructive file sources have a name of the form:
3043 /path/to/Tnnnn-NAME(%[LR])?.wav
3045 the task here is to replace NAME with the new name.
3048 /* find last slash */
3052 string::size_type slash;
3053 string::size_type dash;
3055 if ((slash = path.find_last_of ('/')) == string::npos) {
3059 dir = path.substr (0, slash+1);
3061 /* '-' is not a legal character for the NAME part of the path */
3063 if ((dash = path.find_last_of ('-')) == string::npos) {
3067 prefix = path.substr (slash+1, dash-(slash+1));
3072 path += new_legalized;
3073 path += ".wav"; /* XXX gag me with a spoon */
3077 /* non-destructive file sources have a name of the form:
3079 /path/to/NAME-nnnnn(%[LR])?.ext
3081 the task here is to replace NAME with the new name.
3086 string::size_type slash;
3087 string::size_type dash;
3088 string::size_type postfix;
3090 /* find last slash */
3092 if ((slash = path.find_last_of ('/')) == string::npos) {
3096 dir = path.substr (0, slash+1);
3098 /* '-' is not a legal character for the NAME part of the path */
3100 if ((dash = path.find_last_of ('-')) == string::npos) {
3104 suffix = path.substr (dash+1);
3106 // Suffix is now everything after the dash. Now we need to eliminate
3107 // the nnnnn part, which is done by either finding a '%' or a '.'
3109 postfix = suffix.find_last_of ("%");
3110 if (postfix == string::npos) {
3111 postfix = suffix.find_last_of ('.');
3114 if (postfix != string::npos) {
3115 suffix = suffix.substr (postfix);
3117 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3121 const uint32_t limit = 10000;
3122 char buf[PATH_MAX+1];
3124 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3126 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3128 if (access (buf, F_OK) != 0) {
3136 error << "FATAL ERROR! Could not find a " << endl;
3144 /** Return the full path (in some session directory) for a new embedded source.
3145 * \a name must be a session-unique name that does not contain slashes
3146 * (e.g. as returned by new_*_source_name)
3149 Session::new_source_path_from_name (DataType type, const string& name)
3151 assert(name.find("/") == string::npos);
3153 SessionDirectory sdir(get_best_session_directory_for_new_source());
3156 if (type == DataType::AUDIO) {
3157 p = sdir.sound_path();
3158 } else if (type == DataType::MIDI) {
3159 p = sdir.midi_path();
3161 error << "Unknown source type, unable to create file path" << endmsg;
3166 return p.to_string();
3170 Session::peak_path (Glib::ustring base) const
3172 sys::path peakfile_path(_session_dir->peak_path());
3173 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3174 return peakfile_path.to_string();
3177 /** Return a unique name based on \a base for a new internal audio source */
3179 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3183 char buf[PATH_MAX+1];
3184 const uint32_t limit = 10000;
3188 legalized = legalize_for_path (base);
3190 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3191 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3193 vector<space_and_path>::iterator i;
3194 uint32_t existing = 0;
3196 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3198 SessionDirectory sdir((*i).path);
3200 spath = sdir.sound_path().to_string();
3205 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3206 spath.c_str(), cnt, legalized.c_str());
3207 } else if (nchan == 2) {
3209 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3210 spath.c_str(), cnt, legalized.c_str());
3212 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3213 spath.c_str(), cnt, legalized.c_str());
3215 } else if (nchan < 26) {
3216 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3217 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3219 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3220 spath.c_str(), cnt, legalized.c_str());
3229 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3230 } else if (nchan == 2) {
3232 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3234 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3236 } else if (nchan < 26) {
3237 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3239 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3243 if (sys::exists(buf)) {
3249 if (existing == 0) {
3254 error << string_compose(
3255 _("There are already %1 recordings for %2, which I consider too many."),
3256 limit, base) << endmsg;
3258 throw failed_constructor();
3262 return Glib::path_get_basename(buf);
3265 /** Create a new embedded audio source */
3266 boost::shared_ptr<AudioFileSource>
3267 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3269 const size_t n_chans = ds.n_channels().n_audio();
3270 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3271 const string path = new_source_path_from_name(DataType::AUDIO, name);
3272 return boost::dynamic_pointer_cast<AudioFileSource> (
3273 SourceFactory::createWritable (
3274 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3277 /** Return a unique name based on \a base for a new internal MIDI source */
3279 Session::new_midi_source_name (const string& base)
3282 char buf[PATH_MAX+1];
3283 const uint32_t limit = 10000;
3287 legalized = legalize_for_path (base);
3289 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3290 for (cnt = 1; cnt <= limit; ++cnt) {
3292 vector<space_and_path>::iterator i;
3293 uint32_t existing = 0;
3295 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3297 SessionDirectory sdir((*i).path);
3299 sys::path p = sdir.midi_path();
3302 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3304 if (sys::exists (buf)) {
3309 if (existing == 0) {
3314 error << string_compose(
3315 _("There are already %1 recordings for %2, which I consider too many."),
3316 limit, base) << endmsg;
3318 throw failed_constructor();
3322 return Glib::path_get_basename(buf);
3326 /** Create a new embedded MIDI source */
3327 boost::shared_ptr<MidiSource>
3328 Session::create_midi_source_for_session (MidiDiskstream& ds)
3330 const string name = new_midi_source_name (ds.name());
3331 const string path = new_source_path_from_name (DataType::MIDI, name);
3333 return boost::dynamic_pointer_cast<SMFSource> (
3334 SourceFactory::createWritable (
3335 DataType::MIDI, *this, path, true, false, frame_rate()));
3339 /* Playlist management */
3341 boost::shared_ptr<Playlist>
3342 Session::playlist_by_name (string name)
3344 Glib::Mutex::Lock lm (playlist_lock);
3345 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3346 if ((*i)->name() == name) {
3350 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3351 if ((*i)->name() == name) {
3356 return boost::shared_ptr<Playlist>();
3360 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3362 Glib::Mutex::Lock lm (playlist_lock);
3363 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3364 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3365 list.push_back (*i);
3368 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3369 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3370 list.push_back (*i);
3376 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3378 if (playlist->hidden()) {
3383 Glib::Mutex::Lock lm (playlist_lock);
3384 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3385 playlists.insert (playlists.begin(), playlist);
3386 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3387 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3392 playlist->release();
3397 PlaylistAdded (playlist); /* EMIT SIGNAL */
3401 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3404 Glib::Mutex::Lock lm (playlist_lock);
3405 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3408 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3415 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3417 boost::shared_ptr<Playlist> pl(wpl.lock());
3423 PlaylistList::iterator x;
3426 /* its not supposed to be visible */
3431 Glib::Mutex::Lock lm (playlist_lock);
3435 unused_playlists.insert (pl);
3437 if ((x = playlists.find (pl)) != playlists.end()) {
3438 playlists.erase (x);
3444 playlists.insert (pl);
3446 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3447 unused_playlists.erase (x);
3454 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3456 if (_state_of_the_state & Deletion) {
3460 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3467 Glib::Mutex::Lock lm (playlist_lock);
3469 PlaylistList::iterator i;
3471 i = find (playlists.begin(), playlists.end(), playlist);
3472 if (i != playlists.end()) {
3473 playlists.erase (i);
3476 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3477 if (i != unused_playlists.end()) {
3478 unused_playlists.erase (i);
3485 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3489 Session::set_audition (boost::shared_ptr<Region> r)
3491 pending_audition_region = r;
3492 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3493 schedule_butler_transport_work ();
3497 Session::audition_playlist ()
3499 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3500 ev->region.reset ();
3505 Session::non_realtime_set_audition ()
3507 if (!pending_audition_region) {
3508 auditioner->audition_current_playlist ();
3510 auditioner->audition_region (pending_audition_region);
3511 pending_audition_region.reset ();
3513 AuditionActive (true); /* EMIT SIGNAL */
3517 Session::audition_region (boost::shared_ptr<Region> r)
3519 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3525 Session::cancel_audition ()
3527 if (auditioner->active()) {
3528 auditioner->cancel_audition ();
3529 AuditionActive (false); /* EMIT SIGNAL */
3534 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3536 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3540 Session::remove_empty_sounds ()
3542 vector<string> audio_filenames;
3544 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3546 Glib::Mutex::Lock lm (source_lock);
3548 TapeFileMatcher tape_file_matcher;
3550 remove_if (audio_filenames.begin(), audio_filenames.end(),
3551 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3553 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3555 sys::path audio_file_path (_session_dir->sound_path());
3557 audio_file_path /= *i;
3559 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3563 sys::remove (audio_file_path);
3564 const string peakfile = peak_path (audio_file_path.to_string());
3565 sys::remove (peakfile);
3567 catch (const sys::filesystem_error& err)
3569 error << err.what() << endmsg;
3576 Session::is_auditioning () const
3578 /* can be called before we have an auditioner object */
3580 return auditioner->active();
3587 Session::set_all_solo (bool yn)
3589 shared_ptr<RouteList> r = routes.reader ();
3591 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3592 if (!(*i)->is_hidden()) {
3593 (*i)->set_solo (yn, this);
3601 Session::set_all_listen (bool yn)
3603 shared_ptr<RouteList> r = routes.reader ();
3605 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3606 if (!(*i)->is_hidden()) {
3607 (*i)->set_listen (yn, this);
3615 Session::set_all_mute (bool yn)
3617 shared_ptr<RouteList> r = routes.reader ();
3619 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3620 if (!(*i)->is_hidden()) {
3621 (*i)->set_mute (yn, this);
3629 Session::n_diskstreams () const
3633 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3635 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3636 if (!(*i)->hidden()) {
3644 Session::graph_reordered ()
3646 /* don't do this stuff if we are setting up connections
3647 from a set_state() call or creating new tracks.
3650 if (_state_of_the_state & InitialConnecting) {
3654 /* every track/bus asked for this to be handled but it was deferred because
3655 we were connecting. do it now.
3658 request_input_change_handling ();
3662 /* force all diskstreams to update their capture offset values to
3663 reflect any changes in latencies within the graph.
3666 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3668 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3669 (*i)->set_capture_offset ();
3674 Session::record_disenable_all ()
3676 record_enable_change_all (false);
3680 Session::record_enable_all ()
3682 record_enable_change_all (true);
3686 Session::record_enable_change_all (bool yn)
3688 shared_ptr<RouteList> r = routes.reader ();
3690 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3691 boost::shared_ptr<Track> t;
3693 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3694 t->set_record_enable (yn, this);
3698 /* since we don't keep rec-enable state, don't mark session dirty */
3702 Session::add_processor (Processor* processor)
3704 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3709 Session::remove_processor (Processor* processor)
3713 PortInsert* port_insert;
3715 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3716 insert_bitset[port_insert->bit_slot()] = false;
3717 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3718 send_bitset[send->bit_slot()] = false;
3719 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3720 return_bitset[send->bit_slot()] = false;
3727 Session::available_capture_duration ()
3729 float sample_bytes_on_disk = 4.0; // keep gcc happy
3731 switch (config.get_native_file_data_format()) {
3733 sample_bytes_on_disk = 4.0;
3737 sample_bytes_on_disk = 3.0;
3741 sample_bytes_on_disk = 2.0;
3745 /* impossible, but keep some gcc versions happy */
3746 fatal << string_compose (_("programming error: %1"),
3747 X_("illegal native file data format"))
3752 double scale = 4096.0 / sample_bytes_on_disk;
3754 if (_total_free_4k_blocks * scale > (double) max_frames) {
3758 return (nframes_t) floor (_total_free_4k_blocks * scale);
3762 Session::add_bundle (shared_ptr<Bundle> bundle)
3765 RCUWriter<BundleList> writer (_bundles);
3766 boost::shared_ptr<BundleList> b = writer.get_copy ();
3767 b->push_back (bundle);
3770 BundleAdded (bundle); /* EMIT SIGNAL */
3776 Session::remove_bundle (shared_ptr<Bundle> bundle)
3778 bool removed = false;
3781 RCUWriter<BundleList> writer (_bundles);
3782 boost::shared_ptr<BundleList> b = writer.get_copy ();
3783 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3785 if (i != b->end()) {
3792 BundleRemoved (bundle); /* EMIT SIGNAL */
3799 Session::bundle_by_name (string name) const
3801 boost::shared_ptr<BundleList> b = _bundles.reader ();
3803 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3804 if ((*i)->name() == name) {
3809 return boost::shared_ptr<Bundle> ();
3813 Session::tempo_map_changed (Change ignored)
3817 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3818 (*i)->update_after_tempo_map_change ();
3821 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3822 (*i)->update_after_tempo_map_change ();
3828 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3829 * the given count with the current block size.
3832 Session::ensure_buffers (ChanCount howmany)
3834 if (current_block_size == 0) {
3835 return; // too early? (is this ok?)
3838 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3839 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3840 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3841 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3842 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3845 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3849 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3851 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3852 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3857 Session::next_insert_id ()
3859 /* this doesn't really loop forever. just think about it */
3862 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3863 if (!insert_bitset[n]) {
3864 insert_bitset[n] = true;
3870 /* none available, so resize and try again */
3872 insert_bitset.resize (insert_bitset.size() + 16, false);
3877 Session::next_send_id ()
3879 /* this doesn't really loop forever. just think about it */
3882 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3883 if (!send_bitset[n]) {
3884 send_bitset[n] = true;
3890 /* none available, so resize and try again */
3892 send_bitset.resize (send_bitset.size() + 16, false);
3897 Session::next_return_id ()
3899 /* this doesn't really loop forever. just think about it */
3902 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3903 if (!return_bitset[n]) {
3904 return_bitset[n] = true;
3910 /* none available, so resize and try again */
3912 return_bitset.resize (return_bitset.size() + 16, false);
3917 Session::mark_send_id (uint32_t id)
3919 if (id >= send_bitset.size()) {
3920 send_bitset.resize (id+16, false);
3922 if (send_bitset[id]) {
3923 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3925 send_bitset[id] = true;
3929 Session::mark_return_id (uint32_t id)
3931 if (id >= return_bitset.size()) {
3932 return_bitset.resize (id+16, false);
3934 if (return_bitset[id]) {
3935 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3937 return_bitset[id] = true;
3941 Session::mark_insert_id (uint32_t id)
3943 if (id >= insert_bitset.size()) {
3944 insert_bitset.resize (id+16, false);
3946 if (insert_bitset[id]) {
3947 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3949 insert_bitset[id] = true;
3952 /* Named Selection management */
3955 Session::named_selection_by_name (string name)
3957 Glib::Mutex::Lock lm (named_selection_lock);
3958 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3959 if ((*i)->name == name) {
3967 Session::add_named_selection (NamedSelection* named_selection)
3970 Glib::Mutex::Lock lm (named_selection_lock);
3971 named_selections.insert (named_selections.begin(), named_selection);
3974 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3980 NamedSelectionAdded (); /* EMIT SIGNAL */
3984 Session::remove_named_selection (NamedSelection* named_selection)
3986 bool removed = false;
3989 Glib::Mutex::Lock lm (named_selection_lock);
3991 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3993 if (i != named_selections.end()) {
3995 named_selections.erase (i);
4002 NamedSelectionRemoved (); /* EMIT SIGNAL */
4007 Session::reset_native_file_format ()
4009 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4011 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4012 (*i)->reset_write_sources (false);
4017 Session::route_name_unique (string n) const
4019 shared_ptr<RouteList> r = routes.reader ();
4021 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4022 if ((*i)->name() == n) {
4031 Session::route_name_internal (string n) const
4033 if (auditioner && auditioner->name() == n) {
4037 if (_click_io && _click_io->name() == n) {
4045 Session::n_playlists () const
4047 Glib::Mutex::Lock lm (playlist_lock);
4048 return playlists.size();
4052 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4054 if (!force && howmany <= _npan_buffers) {
4058 if (_pan_automation_buffer) {
4060 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4061 delete [] _pan_automation_buffer[i];
4064 delete [] _pan_automation_buffer;
4067 _pan_automation_buffer = new pan_t*[howmany];
4069 for (uint32_t i = 0; i < howmany; ++i) {
4070 _pan_automation_buffer[i] = new pan_t[nframes];
4073 _npan_buffers = howmany;
4077 Session::freeze (InterThreadInfo& itt)
4079 shared_ptr<RouteList> r = routes.reader ();
4081 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4083 boost::shared_ptr<Track> t;
4085 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4086 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4096 boost::shared_ptr<Region>
4097 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4098 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4099 InterThreadInfo& itt, bool enable_processing)
4101 boost::shared_ptr<Region> result;
4102 boost::shared_ptr<Playlist> playlist;
4103 boost::shared_ptr<AudioFileSource> fsource;
4105 char buf[PATH_MAX+1];
4106 ChanCount nchans(track.audio_diskstream()->n_channels());
4108 nframes_t this_chunk;
4111 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4112 const string sound_dir = sdir.sound_path().to_string();
4113 nframes_t len = end - start;
4116 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4117 end, start) << endmsg;
4121 // any bigger than this seems to cause stack overflows in called functions
4122 const nframes_t chunk_size = (128 * 1024)/4;
4124 // block all process callback handling
4126 block_processing ();
4128 /* call tree *MUST* hold route_lock */
4130 if ((playlist = track.diskstream()->playlist()) == 0) {
4134 /* external redirects will be a problem */
4136 if (track.has_external_redirects()) {
4140 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4142 for (x = 0; x < 99999; ++x) {
4143 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4144 if (access (buf, F_OK) != 0) {
4150 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4155 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4156 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4159 catch (failed_constructor& err) {
4160 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4164 srcs.push_back (fsource);
4167 /* XXX need to flush all redirects */
4172 /* create a set of reasonably-sized buffers */
4173 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4174 buffers.set_count(nchans);
4176 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4177 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4179 afs->prepare_for_peakfile_writes ();
4182 while (to_do && !itt.cancel) {
4184 this_chunk = min (to_do, chunk_size);
4186 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4191 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4192 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4195 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4201 start += this_chunk;
4202 to_do -= this_chunk;
4204 itt.progress = (float) (1.0 - ((double) to_do / len));
4213 xnow = localtime (&now);
4215 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4216 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4219 afs->update_header (position, *xnow, now);
4220 afs->flush_header ();
4224 /* construct a region to represent the bounced material */
4226 result = RegionFactory::create (srcs, 0,
4227 srcs.front()->length(srcs.front()->timeline_position()),
4228 region_name_from_path (srcs.front()->name(), true));
4233 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4234 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4237 afs->mark_for_remove ();
4240 (*src)->drop_references ();
4244 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4245 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4248 afs->done_with_peakfile_writes ();
4252 unblock_processing ();
4258 Session::get_silent_buffers (ChanCount count)
4260 assert(_silent_buffers->available() >= count);
4261 _silent_buffers->set_count(count);
4263 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4264 for (size_t i= 0; i < count.get(*t); ++i) {
4265 _silent_buffers->get(*t, i).clear();
4269 return *_silent_buffers;
4273 Session::get_scratch_buffers (ChanCount count)
4275 if (count != ChanCount::ZERO) {
4276 assert(_scratch_buffers->available() >= count);
4277 _scratch_buffers->set_count(count);
4279 _scratch_buffers->set_count (_scratch_buffers->available());
4282 return *_scratch_buffers;
4286 Session::get_mix_buffers (ChanCount count)
4288 assert(_mix_buffers->available() >= count);
4289 _mix_buffers->set_count(count);
4290 return *_mix_buffers;
4294 Session::ntracks () const
4297 shared_ptr<RouteList> r = routes.reader ();
4299 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4300 if (boost::dynamic_pointer_cast<Track> (*i)) {
4309 Session::nbusses () const
4312 shared_ptr<RouteList> r = routes.reader ();
4314 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4315 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4324 Session::add_automation_list(AutomationList *al)
4326 automation_lists[al->id()] = al;
4330 Session::compute_initial_length ()
4332 return _engine.frame_rate() * 60 * 5;
4336 Session::sync_order_keys (std::string const & base)
4338 if (!Config->get_sync_all_route_ordering()) {
4339 /* leave order keys as they are */
4343 boost::shared_ptr<RouteList> r = routes.reader ();
4345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4346 (*i)->sync_order_keys (base);
4349 Route::SyncOrderKeys (base); // EMIT SIGNAL
4353 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4355 Session::have_rec_enabled_diskstream () const
4357 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4360 /** Update the state of our rec-enabled diskstreams flag */
4362 Session::update_have_rec_enabled_diskstream ()
4364 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4365 DiskstreamList::iterator i = dsl->begin ();
4366 while (i != dsl->end () && (*i)->record_enabled () == false) {
4370 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4372 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4374 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4375 RecordStateChanged (); /* EMIT SIGNAL */
4380 Session::listen_position_changed ()
4384 switch (Config->get_listen_position()) {
4385 case AfterFaderListen:
4389 case PreFaderListen:
4394 boost::shared_ptr<RouteList> r = routes.reader ();
4396 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4397 (*i)->put_control_outs_at (p);
4402 Session::solo_control_mode_changed ()
4404 /* cancel all solo or all listen when solo control mode changes */
4406 if (Config->get_solo_control_is_listen_control()) {
4407 set_all_solo (false);
4409 set_all_listen (false);
4414 Session::route_group_changed ()
4416 RouteGroupChanged (); /* EMIT SIGNAL */