2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/filename_extensions.h"
65 #include "ardour/internal_send.h"
66 #include "ardour/io_processor.h"
67 #include "ardour/midi_diskstream.h"
68 #include "ardour/midi_playlist.h"
69 #include "ardour/midi_region.h"
70 #include "ardour/midi_track.h"
71 #include "ardour/named_selection.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin_insert.h"
74 #include "ardour/port_insert.h"
75 #include "ardour/processor.h"
76 #include "ardour/recent_sessions.h"
77 #include "ardour/region_factory.h"
78 #include "ardour/return.h"
79 #include "ardour/route_group.h"
80 #include "ardour/send.h"
81 #include "ardour/session.h"
82 #include "ardour/session_directory.h"
83 #include "ardour/session_directory.h"
84 #include "ardour/session_metadata.h"
85 #include "ardour/slave.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/tape_file_matcher.h"
89 #include "ardour/tempo.h"
90 #include "ardour/utils.h"
95 using namespace ARDOUR;
97 using boost::shared_ptr;
99 bool Session::_disable_all_loaded_plugins = false;
101 sigc::signal<void,std::string> Session::Dialog;
102 sigc::signal<int> Session::AskAboutPendingState;
103 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
109 sigc::signal<void> Session::AutoBindingOn;
110 sigc::signal<void> Session::AutoBindingOff;
111 sigc::signal<void, std::string, std::string> Session::Exported;
113 Session::Session (AudioEngine &eng,
114 const string& fullpath,
115 const string& snapshot_name,
119 _target_transport_speed (0.0),
120 _requested_return_frame (-1),
121 _scratch_buffers(new BufferSet()),
122 _silent_buffers(new BufferSet()),
123 _mix_buffers(new BufferSet()),
125 _mmc_port (default_mmc_port),
126 _mtc_port (default_mtc_port),
127 _midi_port (default_midi_port),
128 _midi_clock_port (default_midi_clock_port),
129 _session_dir (new SessionDirectory(fullpath)),
130 pending_events (2048),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
134 midi_thread (pthread_t (0)),
135 midi_requests (128), // the size of this should match the midi request pool size
136 diskstreams (new DiskstreamList),
137 routes (new RouteList),
138 _total_free_4k_blocks (0),
139 _bundles (new BundleList),
140 _bundle_xml_node (0),
143 click_emphasis_data (0),
145 _metadata (new SessionMetadata()),
146 _have_rec_enabled_diskstream (false)
151 interpolation.add_channel_to (0, 0);
153 if (!eng.connected()) {
154 throw failed_constructor();
157 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
159 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
160 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
162 first_stage_init (fullpath, snapshot_name);
164 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
167 if (create (new_session, mix_template, compute_initial_length())) {
169 throw failed_constructor ();
173 if (second_stage_init (new_session)) {
175 throw failed_constructor ();
178 store_recent_sessions(_name, _path);
180 bool was_dirty = dirty();
182 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
184 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
185 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _target_transport_speed (0.0),
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 post_transport_work((PostTransportWork)0),
218 _send_smpte_update (false),
219 midi_thread (pthread_t (0)),
221 diskstreams (new DiskstreamList),
222 routes (new RouteList),
223 _total_free_4k_blocks (0),
224 _bundles (new BundleList),
225 _bundle_xml_node (0),
226 _click_io ((IO *) 0),
228 click_emphasis_data (0),
230 _metadata (new SessionMetadata()),
231 _have_rec_enabled_diskstream (false)
235 interpolation.add_channel_to (0, 0);
237 if (!eng.connected()) {
238 throw failed_constructor();
241 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
243 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
244 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
246 if (n_physical_inputs) {
247 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
250 if (n_physical_outputs) {
251 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
254 first_stage_init (fullpath, snapshot_name);
256 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
259 if (create (new_session, string(), initial_length)) {
261 throw failed_constructor ();
266 /* set up Master Out and Control Out if necessary */
271 if (master_out_channels) {
272 ChanCount count(DataType::AUDIO, master_out_channels);
273 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
274 r->input()->ensure_io (count, false, this);
275 r->output()->ensure_io (count, false, this);
276 r->set_remote_control_id (control_id);
280 /* prohibit auto-connect to master, because there isn't one */
281 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
284 if (control_out_channels) {
285 ChanCount count(DataType::AUDIO, control_out_channels);
286 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
287 r->input()->ensure_io (count, false, this);
288 r->output()->ensure_io (count, false, this);
289 r->set_remote_control_id (control_id++);
295 add_routes (rl, false);
300 if (no_auto_connect()) {
301 input_ac = AutoConnectOption (0);
302 output_ac = AutoConnectOption (0);
305 Config->set_input_auto_connect (input_ac);
306 Config->set_output_auto_connect (output_ac);
308 if (second_stage_init (new_session)) {
310 throw failed_constructor ();
313 store_recent_sessions (_name, _path);
315 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
317 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
328 /* if we got to here, leaving pending capture state around
332 remove_pending_capture_state ();
334 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
336 _engine.remove_session ();
338 GoingAway (); /* EMIT SIGNAL */
344 /* clear history so that no references to objects are held any more */
348 /* clear state tree so that no references to objects are held any more */
352 /* reset dynamic state version back to default */
354 Stateful::loading_state_version = 0;
356 terminate_butler_thread ();
357 //terminate_midi_thread ();
359 if (click_data != default_click) {
360 delete [] click_data;
363 if (click_emphasis_data != default_click_emphasis) {
364 delete [] click_emphasis_data;
369 delete _scratch_buffers;
370 delete _silent_buffers;
373 AudioDiskstream::free_working_buffers();
375 Route::SyncOrderKeys.clear();
377 #undef TRACK_DESTRUCTION
378 #ifdef TRACK_DESTRUCTION
379 cerr << "delete named selections\n";
380 #endif /* TRACK_DESTRUCTION */
381 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
382 NamedSelectionList::iterator tmp;
391 #ifdef TRACK_DESTRUCTION
392 cerr << "delete playlists\n";
393 #endif /* TRACK_DESTRUCTION */
394 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
395 PlaylistList::iterator tmp;
400 (*i)->drop_references ();
405 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
406 PlaylistList::iterator tmp;
411 (*i)->drop_references ();
417 unused_playlists.clear ();
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete regions\n";
421 #endif /* TRACK_DESTRUCTION */
423 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
424 RegionList::iterator tmp;
429 i->second->drop_references ();
436 #ifdef TRACK_DESTRUCTION
437 cerr << "delete routes\n";
438 #endif /* TRACK_DESTRUCTION */
440 RCUWriter<RouteList> writer (routes);
441 boost::shared_ptr<RouteList> r = writer.get_copy ();
442 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
443 (*i)->drop_references ();
446 /* writer goes out of scope and updates master */
451 #ifdef TRACK_DESTRUCTION
452 cerr << "delete diskstreams\n";
453 #endif /* TRACK_DESTRUCTION */
455 RCUWriter<DiskstreamList> dwriter (diskstreams);
456 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
457 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
458 (*i)->drop_references ();
462 diskstreams.flush ();
464 #ifdef TRACK_DESTRUCTION
465 cerr << "delete audio sources\n";
466 #endif /* TRACK_DESTRUCTION */
467 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
468 SourceMap::iterator tmp;
473 i->second->drop_references ();
480 #ifdef TRACK_DESTRUCTION
481 cerr << "delete route groups\n";
482 #endif /* TRACK_DESTRUCTION */
483 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
487 Crossfade::set_buffer_size (0);
493 Session::set_worst_io_latencies ()
495 _worst_output_latency = 0;
496 _worst_input_latency = 0;
498 if (!_engine.connected()) {
502 boost::shared_ptr<RouteList> r = routes.reader ();
504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
505 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
506 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
511 Session::when_engine_running ()
513 string first_physical_output;
515 BootMessage (_("Set block size and sample rate"));
517 set_block_size (_engine.frames_per_cycle());
518 set_frame_rate (_engine.frame_rate());
520 BootMessage (_("Using configuration"));
522 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
524 /* every time we reconnect, recompute worst case output latencies */
526 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
528 if (synced_to_jack()) {
529 _engine.transport_stop ();
532 if (config.get_jack_time_master()) {
533 _engine.transport_locate (_transport_frame);
541 _click_io.reset (new ClickIO (*this, "click"));
543 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
545 /* existing state for Click */
548 if (Stateful::loading_state_version < 3000) {
549 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
551 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
556 _clicking = Config->get_clicking ();
560 error << _("could not setup Click I/O") << endmsg;
567 /* default state for Click: dual-mono to first 2 physical outputs */
569 for (int physport = 0; physport < 2; ++physport) {
570 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
572 if (physical_output.length()) {
573 if (_click_io->add_port (physical_output, this)) {
574 // relax, even though its an error
579 if (_click_io->n_ports () > ChanCount::ZERO) {
580 _clicking = Config->get_clicking ();
585 catch (failed_constructor& err) {
586 error << _("cannot setup Click I/O") << endmsg;
589 BootMessage (_("Compute I/O Latencies"));
591 set_worst_io_latencies ();
594 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
597 BootMessage (_("Set up standard connections"));
599 /* Create a set of Bundle objects that map
600 to the physical I/O currently available. We create both
601 mono and stereo bundles, so that the common cases of mono
602 and stereo tracks get bundles to put in their mixer strip
603 in / out menus. There may be a nicer way of achieving that;
604 it doesn't really scale that well to higher channel counts
607 /* mono output bundles */
609 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
611 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
613 shared_ptr<Bundle> c (new Bundle (buf, true));
614 c->add_channel (_("mono"));
615 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
620 /* stereo output bundles */
622 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
623 if (np + 1 < n_physical_outputs) {
625 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
626 shared_ptr<Bundle> c (new Bundle (buf, true));
627 c->add_channel (_("L"));
628 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
629 c->add_channel (_("R"));
630 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
636 /* mono input bundles */
638 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
640 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
642 shared_ptr<Bundle> c (new Bundle (buf, false));
643 c->add_channel (_("mono"));
644 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
649 /* stereo input bundles */
651 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
652 if (np + 1 < n_physical_inputs) {
654 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
656 shared_ptr<Bundle> c (new Bundle (buf, false));
657 c->add_channel (_("L"));
658 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
659 c->add_channel (_("R"));
660 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
666 BootMessage (_("Setup signal flow and plugins"));
670 if (!no_auto_connect()) {
672 if (_master_out && Config->get_auto_connect_standard_busses()) {
674 /* if requested auto-connect the outputs to the first N physical ports.
677 uint32_t limit = _master_out->n_outputs().n_total();
679 for (uint32_t n = 0; n < limit; ++n) {
680 Port* p = _master_out->output()->nth (n);
681 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
683 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
684 if (_master_out->output()->connect (p, connect_to, this)) {
685 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
695 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
696 are undefined, at best.
699 /* control out listens to master bus (but ignores it
700 under some conditions)
703 uint32_t limit = _control_out->n_inputs().n_audio();
706 for (uint32_t n = 0; n < limit; ++n) {
707 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
708 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
711 string connect_to = o->name();
712 if (_control_out->input()->connect (p, connect_to, this)) {
713 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
721 /* if control out is not connected,
722 connect control out to physical outs, but use ones after the master if possible
725 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
727 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
729 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
732 _control_out->output()->connect_ports_to_bundle (b, this);
734 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
735 Config->get_monitor_bus_preferred_bundle())
741 /* XXX this logic is wrong for mixed port types */
743 uint32_t shift = _master_out->n_outputs().n_audio();
744 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
745 limit = _control_out->n_outputs().n_audio();
747 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
749 for (uint32_t n = 0; n < limit; ++n) {
751 Port* p = _control_out->output()->nth (n);
752 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
754 if (!connect_to.empty()) {
755 if (_control_out->output()->connect (p, connect_to, this)) {
756 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
767 /* catch up on send+insert cnts */
769 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
771 /* hook us up to the engine */
773 BootMessage (_("Connect to engine"));
775 _engine.set_session (this);
779 Session::hookup_io ()
781 /* stop graph reordering notifications from
782 causing resorts, etc.
785 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
790 /* we delay creating the auditioner till now because
791 it makes its own connections to ports.
792 the engine has to be running for this to work.
796 auditioner.reset (new Auditioner (*this));
799 catch (failed_constructor& err) {
800 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
804 /* load bundles, which we may have postponed earlier on */
805 if (_bundle_xml_node) {
806 load_bundles (*_bundle_xml_node);
807 delete _bundle_xml_node;
810 /* Tell all IO objects to connect themselves together */
812 IO::enable_connecting ();
814 /* Now reset all panners */
816 Delivery::reset_panners ();
818 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
822 boost::shared_ptr<RouteList> r = routes.reader ();
824 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
826 if ((*x)->is_control() || (*x)->is_master()) {
830 (*x)->listen_via (_control_out,
831 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
836 /* Anyone who cares about input state, wake up and do something */
838 IOConnectionsComplete (); /* EMIT SIGNAL */
840 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
842 /* now handle the whole enchilada as if it was one
848 /* update the full solo state, which can't be
849 correctly determined on a per-route basis, but
850 needs the global overview that only the session
854 update_route_solo_state ();
858 Session::playlist_length_changed ()
860 /* we can't just increase end_location->end() if pl->get_maximum_extent()
861 if larger. if the playlist used to be the longest playlist,
862 and its now shorter, we have to decrease end_location->end(). hence,
863 we have to iterate over all diskstreams and check the
864 playlists currently in use.
870 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
872 boost::shared_ptr<Playlist> playlist;
874 if ((playlist = dstream->playlist()) != 0) {
875 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
878 /* see comment in playlist_length_changed () */
883 Session::record_enabling_legal () const
885 /* this used to be in here, but survey says.... we don't need to restrict it */
886 // if (record_status() == Recording) {
890 if (Config->get_all_safe()) {
897 Session::reset_input_monitor_state ()
899 if (transport_rolling()) {
901 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
903 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
904 if ((*i)->record_enabled ()) {
905 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
906 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
910 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
912 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
913 if ((*i)->record_enabled ()) {
914 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
915 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
922 Session::auto_punch_start_changed (Location* location)
924 replace_event (Event::PunchIn, location->start());
926 if (get_record_enabled() && config.get_punch_in()) {
927 /* capture start has been changed, so save new pending state */
928 save_state ("", true);
933 Session::auto_punch_end_changed (Location* location)
935 nframes_t when_to_stop = location->end();
936 // when_to_stop += _worst_output_latency + _worst_input_latency;
937 replace_event (Event::PunchOut, when_to_stop);
941 Session::auto_punch_changed (Location* location)
943 nframes_t when_to_stop = location->end();
945 replace_event (Event::PunchIn, location->start());
946 //when_to_stop += _worst_output_latency + _worst_input_latency;
947 replace_event (Event::PunchOut, when_to_stop);
951 Session::auto_loop_changed (Location* location)
953 replace_event (Event::AutoLoop, location->end(), location->start());
955 if (transport_rolling() && play_loop) {
957 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
959 if (_transport_frame > location->end()) {
960 // relocate to beginning of loop
961 clear_events (Event::LocateRoll);
963 request_locate (location->start(), true);
966 else if (Config->get_seamless_loop() && !loop_changing) {
968 // schedule a locate-roll to refill the diskstreams at the
970 loop_changing = true;
972 if (location->end() > last_loopend) {
973 clear_events (Event::LocateRoll);
974 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
981 last_loopend = location->end();
985 Session::set_auto_punch_location (Location* location)
989 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
990 auto_punch_start_changed_connection.disconnect();
991 auto_punch_end_changed_connection.disconnect();
992 auto_punch_changed_connection.disconnect();
993 existing->set_auto_punch (false, this);
994 remove_event (existing->start(), Event::PunchIn);
995 clear_events (Event::PunchOut);
996 auto_punch_location_changed (0);
1001 if (location == 0) {
1005 if (location->end() <= location->start()) {
1006 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1010 auto_punch_start_changed_connection.disconnect();
1011 auto_punch_end_changed_connection.disconnect();
1012 auto_punch_changed_connection.disconnect();
1014 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1015 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1016 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1018 location->set_auto_punch (true, this);
1021 auto_punch_changed (location);
1023 auto_punch_location_changed (location);
1027 Session::set_auto_loop_location (Location* location)
1031 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1032 auto_loop_start_changed_connection.disconnect();
1033 auto_loop_end_changed_connection.disconnect();
1034 auto_loop_changed_connection.disconnect();
1035 existing->set_auto_loop (false, this);
1036 remove_event (existing->end(), Event::AutoLoop);
1037 auto_loop_location_changed (0);
1042 if (location == 0) {
1046 if (location->end() <= location->start()) {
1047 error << _("Session: you can't use a mark for auto loop") << endmsg;
1051 last_loopend = location->end();
1053 auto_loop_start_changed_connection.disconnect();
1054 auto_loop_end_changed_connection.disconnect();
1055 auto_loop_changed_connection.disconnect();
1057 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1058 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1059 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1061 location->set_auto_loop (true, this);
1063 /* take care of our stuff first */
1065 auto_loop_changed (location);
1067 /* now tell everyone else */
1069 auto_loop_location_changed (location);
1073 Session::locations_added (Location *)
1079 Session::locations_changed ()
1081 _locations.apply (*this, &Session::handle_locations_changed);
1085 Session::handle_locations_changed (Locations::LocationList& locations)
1087 Locations::LocationList::iterator i;
1089 bool set_loop = false;
1090 bool set_punch = false;
1092 for (i = locations.begin(); i != locations.end(); ++i) {
1096 if (location->is_auto_punch()) {
1097 set_auto_punch_location (location);
1100 if (location->is_auto_loop()) {
1101 set_auto_loop_location (location);
1105 if (location->is_start()) {
1106 start_location = location;
1108 if (location->is_end()) {
1109 end_location = location;
1114 set_auto_loop_location (0);
1117 set_auto_punch_location (0);
1124 Session::enable_record ()
1126 /* XXX really atomic compare+swap here */
1127 if (g_atomic_int_get (&_record_status) != Recording) {
1128 g_atomic_int_set (&_record_status, Recording);
1129 _last_record_location = _transport_frame;
1130 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1132 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1133 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1134 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1135 if ((*i)->record_enabled ()) {
1136 (*i)->monitor_input (true);
1141 RecordStateChanged ();
1146 Session::disable_record (bool rt_context, bool force)
1150 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1152 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1153 g_atomic_int_set (&_record_status, Disabled);
1155 if (rs == Recording) {
1156 g_atomic_int_set (&_record_status, Enabled);
1160 // FIXME: timestamp correct? [DR]
1161 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1162 // does this /need/ to be sent in all cases?
1164 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1166 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1167 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1169 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1170 if ((*i)->record_enabled ()) {
1171 (*i)->monitor_input (false);
1176 RecordStateChanged (); /* emit signal */
1179 remove_pending_capture_state ();
1185 Session::step_back_from_record ()
1187 /* XXX really atomic compare+swap here */
1188 if (g_atomic_int_get (&_record_status) == Recording) {
1189 g_atomic_int_set (&_record_status, Enabled);
1191 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1192 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1194 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1195 if ((*i)->record_enabled ()) {
1196 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1197 (*i)->monitor_input (false);
1205 Session::maybe_enable_record ()
1207 g_atomic_int_set (&_record_status, Enabled);
1209 /* this function is currently called from somewhere other than an RT thread.
1210 this save_state() call therefore doesn't impact anything.
1213 save_state ("", true);
1215 if (_transport_speed) {
1216 if (!config.get_punch_in()) {
1220 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1221 RecordStateChanged (); /* EMIT SIGNAL */
1228 Session::audible_frame () const
1234 /* the first of these two possible settings for "offset"
1235 mean that the audible frame is stationary until
1236 audio emerges from the latency compensation
1239 the second means that the audible frame is stationary
1240 until audio would emerge from a physical port
1241 in the absence of any plugin latency compensation
1244 offset = _worst_output_latency;
1246 if (offset > current_block_size) {
1247 offset -= current_block_size;
1249 /* XXX is this correct? if we have no external
1250 physical connections and everything is internal
1251 then surely this is zero? still, how
1252 likely is that anyway?
1254 offset = current_block_size;
1257 if (synced_to_jack()) {
1258 tf = _engine.transport_frame();
1260 tf = _transport_frame;
1265 if (!non_realtime_work_pending()) {
1269 /* check to see if we have passed the first guaranteed
1270 audible frame past our last start position. if not,
1271 return that last start point because in terms
1272 of audible frames, we have not moved yet.
1275 if (_transport_speed > 0.0f) {
1277 if (!play_loop || !have_looped) {
1278 if (tf < _last_roll_location + offset) {
1279 return _last_roll_location;
1287 } else if (_transport_speed < 0.0f) {
1289 /* XXX wot? no backward looping? */
1291 if (tf > _last_roll_location - offset) {
1292 return _last_roll_location;
1304 Session::set_frame_rate (nframes_t frames_per_second)
1306 /** \fn void Session::set_frame_size(nframes_t)
1307 the AudioEngine object that calls this guarantees
1308 that it will not be called while we are also in
1309 ::process(). Its fine to do things that block
1313 _base_frame_rate = frames_per_second;
1317 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1321 // XXX we need some equivalent to this, somehow
1322 // SndFileSource::setup_standard_crossfades (frames_per_second);
1326 /* XXX need to reset/reinstantiate all LADSPA plugins */
1330 Session::set_block_size (nframes_t nframes)
1332 /* the AudioEngine guarantees
1333 that it will not be called while we are also in
1334 ::process(). It is therefore fine to do things that block
1339 current_block_size = nframes;
1341 ensure_buffers(_scratch_buffers->available());
1343 delete [] _gain_automation_buffer;
1344 _gain_automation_buffer = new gain_t[nframes];
1346 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1348 boost::shared_ptr<RouteList> r = routes.reader ();
1350 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1351 (*i)->set_block_size (nframes);
1354 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1355 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1356 (*i)->set_block_size (nframes);
1359 set_worst_io_latencies ();
1364 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1367 nframes_t fade_frames;
1369 /* Don't allow fade of less 1 frame */
1371 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1378 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1382 default_fade_msecs = fade_msecs;
1383 default_fade_steepness = steepness;
1386 // jlc, WTF is this!
1387 Glib::RWLock::ReaderLock lm (route_lock);
1388 AudioRegion::set_default_fade (steepness, fade_frames);
1393 /* XXX have to do this at some point */
1394 /* foreach region using default fade, reset, then
1395 refill_all_diskstream_buffers ();
1400 struct RouteSorter {
1401 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1402 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1404 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1407 if (r1->fed_by.empty()) {
1408 if (r2->fed_by.empty()) {
1409 /* no ardour-based connections inbound to either route. just use signal order */
1410 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1412 /* r2 has connections, r1 does not; run r1 early */
1416 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1423 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1425 shared_ptr<Route> r2;
1427 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1428 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1432 /* make a copy of the existing list of routes that feed r1 */
1434 set<shared_ptr<Route> > existing = r1->fed_by;
1436 /* for each route that feeds r1, recurse, marking it as feeding
1440 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1443 /* r2 is a route that feeds r1 which somehow feeds base. mark
1444 base as being fed by r2
1447 rbase->fed_by.insert (r2);
1451 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1455 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1459 /* now recurse, so that we can mark base as being fed by
1460 all routes that feed r2
1463 trace_terminal (r2, rbase);
1470 Session::resort_routes ()
1472 /* don't do anything here with signals emitted
1473 by Routes while we are being destroyed.
1476 if (_state_of_the_state & Deletion) {
1483 RCUWriter<RouteList> writer (routes);
1484 shared_ptr<RouteList> r = writer.get_copy ();
1485 resort_routes_using (r);
1486 /* writer goes out of scope and forces update */
1491 Session::resort_routes_using (shared_ptr<RouteList> r)
1493 RouteList::iterator i, j;
1495 for (i = r->begin(); i != r->end(); ++i) {
1497 (*i)->fed_by.clear ();
1499 for (j = r->begin(); j != r->end(); ++j) {
1501 /* although routes can feed themselves, it will
1502 cause an endless recursive descent if we
1503 detect it. so don't bother checking for
1511 if ((*j)->feeds (*i)) {
1512 (*i)->fed_by.insert (*j);
1517 for (i = r->begin(); i != r->end(); ++i) {
1518 trace_terminal (*i, *i);
1525 cerr << "finished route resort\n";
1527 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1528 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1535 list<boost::shared_ptr<MidiTrack> >
1536 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1538 char track_name[32];
1539 uint32_t track_id = 0;
1542 RouteList new_routes;
1543 list<boost::shared_ptr<MidiTrack> > ret;
1544 //uint32_t control_id;
1546 // FIXME: need physical I/O and autoconnect stuff for MIDI
1548 /* count existing midi tracks */
1551 shared_ptr<RouteList> r = routes.reader ();
1553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1554 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1555 if (!(*i)->is_hidden()) {
1557 //channels_used += (*i)->n_inputs().n_midi();
1563 vector<string> physinputs;
1564 vector<string> physoutputs;
1566 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1567 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1569 // control_id = ntracks() + nbusses();
1573 /* check for duplicate route names, since we might have pre-existing
1574 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1575 save, close,restart,add new route - first named route is now
1583 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1585 if (route_by_name (track_name) == 0) {
1589 } while (track_id < (UINT_MAX-1));
1591 shared_ptr<MidiTrack> track;
1594 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1596 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1597 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1602 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1603 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1609 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1613 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1614 port = physinputs[(channels_used+x)%nphysical_in];
1617 if (port.length() && track->connect_input (track->input (x), port, this)) {
1623 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1627 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1628 port = physoutputs[(channels_used+x)%nphysical_out];
1629 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1631 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1635 if (port.length() && track->connect_output (track->output (x), port, this)) {
1640 channels_used += track->n_inputs ().n_midi();
1644 track->midi_diskstream()->non_realtime_input_change();
1645 track->set_route_group (route_group, 0);
1647 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1648 //track->set_remote_control_id (control_id);
1650 new_routes.push_back (track);
1651 ret.push_back (track);
1654 catch (failed_constructor &err) {
1655 error << _("Session: could not create new midi track.") << endmsg;
1658 /* we need to get rid of this, since the track failed to be created */
1659 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1662 RCUWriter<DiskstreamList> writer (diskstreams);
1663 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1664 ds->remove (track->midi_diskstream());
1671 catch (AudioEngine::PortRegistrationFailure& pfe) {
1673 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;
1676 /* we need to get rid of this, since the track failed to be created */
1677 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1680 RCUWriter<DiskstreamList> writer (diskstreams);
1681 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1682 ds->remove (track->midi_diskstream());
1693 if (!new_routes.empty()) {
1694 add_routes (new_routes, false);
1695 save_state (_current_snapshot_name);
1701 list<boost::shared_ptr<AudioTrack> >
1702 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1704 char track_name[32];
1705 uint32_t track_id = 0;
1707 uint32_t channels_used = 0;
1709 RouteList new_routes;
1710 list<boost::shared_ptr<AudioTrack> > ret;
1711 uint32_t control_id;
1713 /* count existing audio tracks */
1716 shared_ptr<RouteList> r = routes.reader ();
1718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1719 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1720 if (!(*i)->is_hidden()) {
1722 channels_used += (*i)->n_inputs().n_audio();
1728 vector<string> physinputs;
1729 vector<string> physoutputs;
1731 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1732 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1734 control_id = ntracks() + nbusses() + 1;
1738 /* check for duplicate route names, since we might have pre-existing
1739 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1740 save, close,restart,add new route - first named route is now
1748 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1750 if (route_by_name (track_name) == 0) {
1754 } while (track_id < (UINT_MAX-1));
1756 shared_ptr<AudioTrack> track;
1759 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1761 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1762 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1763 input_channels, output_channels)
1768 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1769 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1770 input_channels, output_channels)
1775 if (!physinputs.empty()) {
1776 uint32_t nphysical_in = physinputs.size();
1778 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1782 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1783 port = physinputs[(channels_used+x)%nphysical_in];
1786 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1792 if (!physoutputs.empty()) {
1793 uint32_t nphysical_out = physoutputs.size();
1795 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1798 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1799 port = physoutputs[(channels_used+x)%nphysical_out];
1800 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1801 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1802 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1806 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1812 channels_used += track->n_inputs ().n_audio();
1814 track->set_route_group (route_group, 0);
1816 track->audio_diskstream()->non_realtime_input_change();
1818 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1819 track->set_remote_control_id (control_id);
1822 new_routes.push_back (track);
1823 ret.push_back (track);
1826 catch (failed_constructor &err) {
1827 error << _("Session: could not create new audio track.") << endmsg;
1830 /* we need to get rid of this, since the track failed to be created */
1831 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1834 RCUWriter<DiskstreamList> writer (diskstreams);
1835 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1836 ds->remove (track->audio_diskstream());
1843 catch (AudioEngine::PortRegistrationFailure& pfe) {
1845 error << pfe.what() << endmsg;
1848 /* we need to get rid of this, since the track failed to be created */
1849 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1852 RCUWriter<DiskstreamList> writer (diskstreams);
1853 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1854 ds->remove (track->audio_diskstream());
1865 if (!new_routes.empty()) {
1866 add_routes (new_routes, true);
1873 Session::set_remote_control_ids ()
1875 RemoteModel m = Config->get_remote_model();
1877 shared_ptr<RouteList> r = routes.reader ();
1879 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1880 if ( MixerOrdered == m) {
1881 long order = (*i)->order_key(N_("signal"));
1882 (*i)->set_remote_control_id( order+1 );
1883 } else if ( EditorOrdered == m) {
1884 long order = (*i)->order_key(N_("editor"));
1885 (*i)->set_remote_control_id( order+1 );
1886 } else if ( UserOrdered == m) {
1887 //do nothing ... only changes to remote id's are initiated by user
1894 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1897 uint32_t bus_id = 1;
1899 uint32_t channels_used = 0;
1902 uint32_t control_id;
1904 /* count existing audio busses */
1907 shared_ptr<RouteList> r = routes.reader ();
1909 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1910 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1912 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1915 channels_used += (*i)->n_inputs().n_audio();
1921 vector<string> physinputs;
1922 vector<string> physoutputs;
1924 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1925 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1927 n_physical_audio_outputs = physoutputs.size();
1928 n_physical_audio_inputs = physinputs.size();
1930 control_id = ntracks() + nbusses() + 1;
1935 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1939 if (route_by_name (bus_name) == 0) {
1943 } while (bus_id < (UINT_MAX-1));
1946 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1948 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1949 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1950 input_channels, output_channels)
1956 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1957 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1958 input_channels, output_channels)
1963 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1966 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1967 port = physinputs[((n+x)%n_physical_audio_inputs)];
1970 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1975 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1978 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1979 port = physoutputs[((n+x)%n_physical_outputs)];
1980 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1982 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1986 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1991 channels_used += bus->n_inputs ().n_audio();
1993 bus->set_route_group (route_group, 0);
1994 bus->set_remote_control_id (control_id);
1997 ret.push_back (bus);
2001 catch (failed_constructor &err) {
2002 error << _("Session: could not create new audio route.") << endmsg;
2006 catch (AudioEngine::PortRegistrationFailure& pfe) {
2007 error << pfe.what() << endmsg;
2017 add_routes (ret, true);
2025 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2029 uint32_t control_id;
2031 uint32_t number = 1;
2033 if (!tree.read (template_path.c_str())) {
2037 XMLNode* node = tree.root();
2039 control_id = ntracks() + nbusses() + 1;
2043 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2045 std::string node_name = IO::name_from_state (*node_copy.children().front());
2047 /* generate a new name by adding a number to the end of the template name */
2050 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2054 if (route_by_name (name) == 0) {
2058 } while (number < UINT_MAX);
2060 if (number == UINT_MAX) {
2061 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2065 IO::set_name_in_state (*node_copy.children().front(), name);
2067 Track::zero_diskstream_id_in_xml (node_copy);
2070 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2073 error << _("Session: cannot create track/bus from template description") << endmsg;
2077 if (boost::dynamic_pointer_cast<Track>(route)) {
2078 /* force input/output change signals so that the new diskstream
2079 picks up the configuration of the route. During session
2080 loading this normally happens in a different way.
2082 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2083 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2086 route->set_remote_control_id (control_id);
2089 ret.push_back (route);
2092 catch (failed_constructor &err) {
2093 error << _("Session: could not create new route from template") << endmsg;
2097 catch (AudioEngine::PortRegistrationFailure& pfe) {
2098 error << pfe.what() << endmsg;
2107 add_routes (ret, true);
2114 Session::add_routes (RouteList& new_routes, bool save)
2117 RCUWriter<RouteList> writer (routes);
2118 shared_ptr<RouteList> r = writer.get_copy ();
2119 r->insert (r->end(), new_routes.begin(), new_routes.end());
2122 /* if there is no control out and we're not in the middle of loading,
2123 resort the graph here. if there is a control out, we will resort
2124 toward the end of this method. if we are in the middle of loading,
2125 we will resort when done.
2128 if (!_control_out && IO::connecting_legal) {
2129 resort_routes_using (r);
2133 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2135 boost::weak_ptr<Route> wpr (*x);
2137 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2138 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2139 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2140 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2141 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2142 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2144 if ((*x)->is_master()) {
2148 if ((*x)->is_control()) {
2149 _control_out = (*x);
2153 if (_control_out && IO::connecting_legal) {
2155 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2156 if ((*x)->is_control() || (*x)->is_master()) {
2159 (*x)->listen_via (_control_out,
2160 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2170 save_state (_current_snapshot_name);
2173 RouteAdded (new_routes); /* EMIT SIGNAL */
2177 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2179 boost::shared_ptr<RouteList> r = routes.reader ();
2180 boost::shared_ptr<Send> s;
2184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2185 if (boost::dynamic_pointer_cast<Track>(*i)) {
2186 if ((s = (*i)->internal_send_for (dest)) != 0) {
2187 s->amp()->gain_control()->set_value (0.0);
2194 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2196 boost::shared_ptr<RouteList> r = routes.reader ();
2197 boost::shared_ptr<Send> s;
2201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2202 if (boost::dynamic_pointer_cast<Track>(*i)) {
2203 if ((s = (*i)->internal_send_for (dest)) != 0) {
2204 s->amp()->gain_control()->set_value (1.0);
2211 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2213 boost::shared_ptr<RouteList> r = routes.reader ();
2214 boost::shared_ptr<Send> s;
2218 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2219 if (boost::dynamic_pointer_cast<Track>(*i)) {
2220 if ((s = (*i)->internal_send_for (dest)) != 0) {
2221 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2228 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2230 boost::shared_ptr<RouteList> r = routes.reader ();
2231 boost::shared_ptr<RouteList> t (new RouteList);
2233 /* only send tracks */
2235 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2236 if (boost::dynamic_pointer_cast<Track>(*i)) {
2241 add_internal_sends (dest, p, t);
2246 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2248 if (dest->is_control() || dest->is_master()) {
2252 if (!dest->internal_return()) {
2253 dest->add_internal_return();
2256 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2258 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2262 (*i)->listen_via (dest, p, true, true);
2267 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2269 /* need to do this in case we're rolling at the time, to prevent false underruns */
2270 dstream->do_refill_with_alloc ();
2272 dstream->set_block_size (current_block_size);
2275 RCUWriter<DiskstreamList> writer (diskstreams);
2276 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2277 ds->push_back (dstream);
2278 /* writer goes out of scope, copies ds back to main */
2281 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2282 /* this will connect to future changes, and check the current length */
2283 diskstream_playlist_changed (dstream);
2285 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2287 dstream->prepare ();
2292 Session::remove_route (shared_ptr<Route> route)
2295 RCUWriter<RouteList> writer (routes);
2296 shared_ptr<RouteList> rs = writer.get_copy ();
2300 /* deleting the master out seems like a dumb
2301 idea, but its more of a UI policy issue
2305 if (route == _master_out) {
2306 _master_out = shared_ptr<Route> ();
2309 if (route == _control_out) {
2311 /* cancel control outs for all routes */
2313 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2314 (*r)->drop_listen (_control_out);
2317 _control_out.reset ();
2320 update_route_solo_state ();
2322 /* writer goes out of scope, forces route list update */
2325 boost::shared_ptr<Track> t;
2326 boost::shared_ptr<Diskstream> ds;
2328 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2329 ds = t->diskstream();
2335 RCUWriter<DiskstreamList> dsl (diskstreams);
2336 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2341 find_current_end ();
2343 // We need to disconnect the routes inputs and outputs
2345 route->input()->disconnect (0);
2346 route->output()->disconnect (0);
2348 update_latency_compensation (false, false);
2351 /* get rid of it from the dead wood collection in the route list manager */
2353 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2357 /* try to cause everyone to drop their references */
2359 route->drop_references ();
2361 sync_order_keys (N_("session"));
2363 /* save the new state of the world */
2365 if (save_state (_current_snapshot_name)) {
2366 save_history (_current_snapshot_name);
2371 Session::route_mute_changed (void* /*src*/)
2377 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2379 boost::shared_ptr<Route> route = wpr.lock();
2381 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2385 if (route->listening()) {
2387 } else if (_listen_cnt > 0) {
2393 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2395 if (solo_update_disabled) {
2400 boost::shared_ptr<Route> route = wpr.lock ();
2403 /* should not happen */
2404 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2408 shared_ptr<RouteList> r = routes.reader ();
2411 if (route->soloed()) {
2417 /* now mod the solo level of all other routes except master & control outs
2418 so that they will be silent if appropriate.
2421 solo_update_disabled = true;
2422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2424 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2426 (*i)->mod_solo_level (delta);
2430 /* make sure master is never muted by solo */
2432 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2433 _master_out->mod_solo_level (1);
2436 /* ditto for control outs make sure master is never muted by solo */
2438 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2439 _control_out->mod_solo_level (1);
2442 solo_update_disabled = false;
2443 update_route_solo_state (r);
2444 SoloChanged (); /* EMIT SIGNAL */
2449 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2451 /* now figure out if anything that matters is soloed */
2453 bool something_soloed = false;
2456 r = routes.reader();
2459 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2460 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2461 something_soloed = true;
2466 if (something_soloed != _non_soloed_outs_muted) {
2467 _non_soloed_outs_muted = something_soloed;
2468 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2473 Session::route_by_name (string name)
2475 shared_ptr<RouteList> r = routes.reader ();
2477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2478 if ((*i)->name() == name) {
2483 return shared_ptr<Route> ((Route*) 0);
2487 Session::route_by_id (PBD::ID id)
2489 shared_ptr<RouteList> r = routes.reader ();
2491 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2492 if ((*i)->id() == id) {
2497 return shared_ptr<Route> ((Route*) 0);
2501 Session::route_by_remote_id (uint32_t id)
2503 shared_ptr<RouteList> r = routes.reader ();
2505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2506 if ((*i)->remote_control_id() == id) {
2511 return shared_ptr<Route> ((Route*) 0);
2515 Session::find_current_end ()
2517 if (_state_of_the_state & Loading) {
2521 nframes_t max = get_maximum_extent ();
2523 if (max > end_location->end()) {
2524 end_location->set_end (max);
2526 DurationChanged(); /* EMIT SIGNAL */
2531 Session::get_maximum_extent () const
2536 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2538 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2539 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2541 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2542 if ((me = pl->get_maximum_extent()) > max) {
2550 boost::shared_ptr<Diskstream>
2551 Session::diskstream_by_name (string name)
2553 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2555 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2556 if ((*i)->name() == name) {
2561 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2564 boost::shared_ptr<Diskstream>
2565 Session::diskstream_by_id (const PBD::ID& id)
2567 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2569 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2570 if ((*i)->id() == id) {
2575 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2578 /* Region management */
2581 Session::new_region_name (string old)
2583 string::size_type last_period;
2585 string::size_type len = old.length() + 64;
2588 if ((last_period = old.find_last_of ('.')) == string::npos) {
2590 /* no period present - add one explicitly */
2593 last_period = old.length() - 1;
2598 number = atoi (old.substr (last_period+1).c_str());
2602 while (number < (UINT_MAX-1)) {
2604 RegionList::const_iterator i;
2609 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2612 for (i = regions.begin(); i != regions.end(); ++i) {
2613 if (i->second->name() == sbuf) {
2618 if (i == regions.end()) {
2623 if (number != (UINT_MAX-1)) {
2627 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2632 Session::region_name (string& result, string base, bool newlevel)
2637 if (base.find("/") != string::npos) {
2638 base = base.substr(base.find_last_of("/") + 1);
2643 Glib::Mutex::Lock lm (region_lock);
2645 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2654 string::size_type pos;
2656 pos = base.find_last_of ('.');
2658 /* pos may be npos, but then we just use entire base */
2660 subbase = base.substr (0, pos);
2665 Glib::Mutex::Lock lm (region_lock);
2667 map<string,uint32_t>::iterator x;
2671 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2673 region_name_map[subbase] = 1;
2676 snprintf (buf, sizeof (buf), ".%d", x->second);
2687 Session::add_region (boost::shared_ptr<Region> region)
2689 vector<boost::shared_ptr<Region> > v;
2690 v.push_back (region);
2695 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2700 Glib::Mutex::Lock lm (region_lock);
2702 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2704 boost::shared_ptr<Region> region = *ii;
2708 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2712 RegionList::iterator x;
2714 for (x = regions.begin(); x != regions.end(); ++x) {
2716 if (region->region_list_equivalent (x->second)) {
2721 if (x == regions.end()) {
2723 pair<RegionList::key_type,RegionList::mapped_type> entry;
2725 entry.first = region->id();
2726 entry.second = region;
2728 pair<RegionList::iterator,bool> x = regions.insert (entry);
2740 /* mark dirty because something has changed even if we didn't
2741 add the region to the region list.
2748 vector<boost::weak_ptr<Region> > v;
2749 boost::shared_ptr<Region> first_r;
2751 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2753 boost::shared_ptr<Region> region = *ii;
2757 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2760 v.push_back (region);
2767 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2768 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2770 update_region_name_map (region);
2774 RegionsAdded (v); /* EMIT SIGNAL */
2780 Session::update_region_name_map (boost::shared_ptr<Region> region)
2782 string::size_type last_period = region->name().find_last_of ('.');
2784 if (last_period != string::npos && last_period < region->name().length() - 1) {
2786 string base = region->name().substr (0, last_period);
2787 string number = region->name().substr (last_period+1);
2788 map<string,uint32_t>::iterator x;
2790 /* note that if there is no number, we get zero from atoi,
2794 region_name_map[base] = atoi (number);
2799 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2801 boost::shared_ptr<Region> region (weak_region.lock ());
2807 if (what_changed & Region::HiddenChanged) {
2808 /* relay hidden changes */
2809 RegionHiddenChange (region);
2812 if (what_changed & NameChanged) {
2813 update_region_name_map (region);
2818 Session::remove_region (boost::weak_ptr<Region> weak_region)
2820 RegionList::iterator i;
2821 boost::shared_ptr<Region> region (weak_region.lock ());
2827 bool removed = false;
2830 Glib::Mutex::Lock lm (region_lock);
2832 if ((i = regions.find (region->id())) != regions.end()) {
2838 /* mark dirty because something has changed even if we didn't
2839 remove the region from the region list.
2845 RegionRemoved(region); /* EMIT SIGNAL */
2849 boost::shared_ptr<Region>
2850 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2852 RegionList::iterator i;
2853 boost::shared_ptr<Region> region;
2855 Glib::Mutex::Lock lm (region_lock);
2857 for (i = regions.begin(); i != regions.end(); ++i) {
2861 if (region->whole_file()) {
2863 if (child->source_equivalent (region)) {
2869 return boost::shared_ptr<Region> ();
2873 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2875 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2876 (*i)->get_region_list_equivalent_regions (region, result);
2880 Session::destroy_region (boost::shared_ptr<Region> region)
2882 vector<boost::shared_ptr<Source> > srcs;
2885 if (region->playlist()) {
2886 region->playlist()->destroy_region (region);
2889 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2890 srcs.push_back (region->source (n));
2894 region->drop_references ();
2896 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2898 (*i)->mark_for_remove ();
2899 (*i)->drop_references ();
2901 cerr << "source was not used by any playlist\n";
2908 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2910 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2911 destroy_region (*i);
2917 Session::remove_last_capture ()
2919 list<boost::shared_ptr<Region> > r;
2921 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2923 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2924 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2927 r.insert (r.end(), l.begin(), l.end());
2932 destroy_regions (r);
2934 save_state (_current_snapshot_name);
2940 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2946 /* Source Management */
2949 Session::add_source (boost::shared_ptr<Source> source)
2951 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2952 pair<SourceMap::iterator,bool> result;
2954 entry.first = source->id();
2955 entry.second = source;
2958 Glib::Mutex::Lock lm (source_lock);
2959 result = sources.insert (entry);
2962 if (result.second) {
2963 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2967 boost::shared_ptr<AudioFileSource> afs;
2969 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2970 if (Config->get_auto_analyse_audio()) {
2971 Analyser::queue_source_for_analysis (source, false);
2977 Session::remove_source (boost::weak_ptr<Source> src)
2979 SourceMap::iterator i;
2980 boost::shared_ptr<Source> source = src.lock();
2987 Glib::Mutex::Lock lm (source_lock);
2989 if ((i = sources.find (source->id())) != sources.end()) {
2994 if (!_state_of_the_state & InCleanup) {
2996 /* save state so we don't end up with a session file
2997 referring to non-existent sources.
3000 save_state (_current_snapshot_name);
3004 boost::shared_ptr<Source>
3005 Session::source_by_id (const PBD::ID& id)
3007 Glib::Mutex::Lock lm (source_lock);
3008 SourceMap::iterator i;
3009 boost::shared_ptr<Source> source;
3011 if ((i = sources.find (id)) != sources.end()) {
3018 boost::shared_ptr<Source>
3019 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3021 Glib::Mutex::Lock lm (source_lock);
3023 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3024 cerr << "comparing " << path << " with " << i->second->name() << endl;
3025 boost::shared_ptr<AudioFileSource> afs
3026 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3028 if (afs && afs->path() == path && chn == afs->channel()) {
3032 return boost::shared_ptr<Source>();
3037 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3040 string old_basename = PBD::basename_nosuffix (oldname);
3041 string new_legalized = legalize_for_path (newname);
3043 /* note: we know (or assume) the old path is already valid */
3047 /* destructive file sources have a name of the form:
3049 /path/to/Tnnnn-NAME(%[LR])?.wav
3051 the task here is to replace NAME with the new name.
3054 /* find last slash */
3058 string::size_type slash;
3059 string::size_type dash;
3061 if ((slash = path.find_last_of ('/')) == string::npos) {
3065 dir = path.substr (0, slash+1);
3067 /* '-' is not a legal character for the NAME part of the path */
3069 if ((dash = path.find_last_of ('-')) == string::npos) {
3073 prefix = path.substr (slash+1, dash-(slash+1));
3078 path += new_legalized;
3079 path += ".wav"; /* XXX gag me with a spoon */
3083 /* non-destructive file sources have a name of the form:
3085 /path/to/NAME-nnnnn(%[LR])?.ext
3087 the task here is to replace NAME with the new name.
3092 string::size_type slash;
3093 string::size_type dash;
3094 string::size_type postfix;
3096 /* find last slash */
3098 if ((slash = path.find_last_of ('/')) == string::npos) {
3102 dir = path.substr (0, slash+1);
3104 /* '-' is not a legal character for the NAME part of the path */
3106 if ((dash = path.find_last_of ('-')) == string::npos) {
3110 suffix = path.substr (dash+1);
3112 // Suffix is now everything after the dash. Now we need to eliminate
3113 // the nnnnn part, which is done by either finding a '%' or a '.'
3115 postfix = suffix.find_last_of ("%");
3116 if (postfix == string::npos) {
3117 postfix = suffix.find_last_of ('.');
3120 if (postfix != string::npos) {
3121 suffix = suffix.substr (postfix);
3123 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3127 const uint32_t limit = 10000;
3128 char buf[PATH_MAX+1];
3130 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3132 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3134 if (access (buf, F_OK) != 0) {
3142 error << "FATAL ERROR! Could not find a " << endl;
3150 /** Return the full path (in some session directory) for a new embedded source.
3151 * \a name must be a session-unique name that does not contain slashes
3152 * (e.g. as returned by new_*_source_name)
3155 Session::new_source_path_from_name (DataType type, const string& name)
3157 assert(name.find("/") == string::npos);
3159 SessionDirectory sdir(get_best_session_directory_for_new_source());
3162 if (type == DataType::AUDIO) {
3163 p = sdir.sound_path();
3164 } else if (type == DataType::MIDI) {
3165 p = sdir.midi_path();
3167 error << "Unknown source type, unable to create file path" << endmsg;
3172 return p.to_string();
3176 Session::peak_path (Glib::ustring base) const
3178 sys::path peakfile_path(_session_dir->peak_path());
3179 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3180 return peakfile_path.to_string();
3183 /** Return a unique name based on \a base for a new internal audio source */
3185 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3189 char buf[PATH_MAX+1];
3190 const uint32_t limit = 10000;
3194 legalized = legalize_for_path (base);
3196 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3197 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3199 vector<space_and_path>::iterator i;
3200 uint32_t existing = 0;
3202 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3204 SessionDirectory sdir((*i).path);
3206 spath = sdir.sound_path().to_string();
3211 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3212 spath.c_str(), cnt, legalized.c_str());
3213 } else if (nchan == 2) {
3215 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3216 spath.c_str(), cnt, legalized.c_str());
3218 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3219 spath.c_str(), cnt, legalized.c_str());
3221 } else if (nchan < 26) {
3222 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3223 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3225 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3226 spath.c_str(), cnt, legalized.c_str());
3235 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3236 } else if (nchan == 2) {
3238 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3240 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3242 } else if (nchan < 26) {
3243 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3245 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3249 if (sys::exists(buf)) {
3255 if (existing == 0) {
3260 error << string_compose(
3261 _("There are already %1 recordings for %2, which I consider too many."),
3262 limit, base) << endmsg;
3264 throw failed_constructor();
3268 return Glib::path_get_basename(buf);
3271 /** Create a new embedded audio source */
3272 boost::shared_ptr<AudioFileSource>
3273 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3275 const size_t n_chans = ds.n_channels().n_audio();
3276 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3277 const string path = new_source_path_from_name(DataType::AUDIO, name);
3278 return boost::dynamic_pointer_cast<AudioFileSource> (
3279 SourceFactory::createWritable (
3280 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3283 /** Return a unique name based on \a base for a new internal MIDI source */
3285 Session::new_midi_source_name (const string& base)
3288 char buf[PATH_MAX+1];
3289 const uint32_t limit = 10000;
3293 legalized = legalize_for_path (base);
3295 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3296 for (cnt = 1; cnt <= limit; ++cnt) {
3298 vector<space_and_path>::iterator i;
3299 uint32_t existing = 0;
3301 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3303 SessionDirectory sdir((*i).path);
3305 sys::path p = sdir.midi_path();
3308 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3310 if (sys::exists (buf)) {
3315 if (existing == 0) {
3320 error << string_compose(
3321 _("There are already %1 recordings for %2, which I consider too many."),
3322 limit, base) << endmsg;
3324 throw failed_constructor();
3328 return Glib::path_get_basename(buf);
3332 /** Create a new embedded MIDI source */
3333 boost::shared_ptr<MidiSource>
3334 Session::create_midi_source_for_session (MidiDiskstream& ds)
3336 const string name = new_midi_source_name (ds.name());
3337 const string path = new_source_path_from_name (DataType::MIDI, name);
3339 return boost::dynamic_pointer_cast<SMFSource> (
3340 SourceFactory::createWritable (
3341 DataType::MIDI, *this, path, true, false, frame_rate()));
3345 /* Playlist management */
3347 boost::shared_ptr<Playlist>
3348 Session::playlist_by_name (string name)
3350 Glib::Mutex::Lock lm (playlist_lock);
3351 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3352 if ((*i)->name() == name) {
3356 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3357 if ((*i)->name() == name) {
3362 return boost::shared_ptr<Playlist>();
3366 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3368 Glib::Mutex::Lock lm (playlist_lock);
3369 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3370 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3371 list.push_back (*i);
3374 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3375 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3376 list.push_back (*i);
3382 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3384 if (playlist->hidden()) {
3389 Glib::Mutex::Lock lm (playlist_lock);
3390 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3391 playlists.insert (playlists.begin(), playlist);
3392 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3393 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3398 playlist->release();
3403 PlaylistAdded (playlist); /* EMIT SIGNAL */
3407 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3410 Glib::Mutex::Lock lm (playlist_lock);
3411 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3414 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3421 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3423 boost::shared_ptr<Playlist> pl(wpl.lock());
3429 PlaylistList::iterator x;
3432 /* its not supposed to be visible */
3437 Glib::Mutex::Lock lm (playlist_lock);
3441 unused_playlists.insert (pl);
3443 if ((x = playlists.find (pl)) != playlists.end()) {
3444 playlists.erase (x);
3450 playlists.insert (pl);
3452 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3453 unused_playlists.erase (x);
3460 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3462 if (_state_of_the_state & Deletion) {
3466 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3473 Glib::Mutex::Lock lm (playlist_lock);
3475 PlaylistList::iterator i;
3477 i = find (playlists.begin(), playlists.end(), playlist);
3478 if (i != playlists.end()) {
3479 playlists.erase (i);
3482 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3483 if (i != unused_playlists.end()) {
3484 unused_playlists.erase (i);
3491 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3495 Session::set_audition (boost::shared_ptr<Region> r)
3497 pending_audition_region = r;
3498 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3499 schedule_butler_transport_work ();
3503 Session::audition_playlist ()
3505 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3506 ev->region.reset ();
3511 Session::non_realtime_set_audition ()
3513 if (!pending_audition_region) {
3514 auditioner->audition_current_playlist ();
3516 auditioner->audition_region (pending_audition_region);
3517 pending_audition_region.reset ();
3519 AuditionActive (true); /* EMIT SIGNAL */
3523 Session::audition_region (boost::shared_ptr<Region> r)
3525 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3531 Session::cancel_audition ()
3533 if (auditioner->active()) {
3534 auditioner->cancel_audition ();
3535 AuditionActive (false); /* EMIT SIGNAL */
3540 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3542 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3546 Session::remove_empty_sounds ()
3548 vector<string> audio_filenames;
3550 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3552 Glib::Mutex::Lock lm (source_lock);
3554 TapeFileMatcher tape_file_matcher;
3556 remove_if (audio_filenames.begin(), audio_filenames.end(),
3557 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3559 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3561 sys::path audio_file_path (_session_dir->sound_path());
3563 audio_file_path /= *i;
3565 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3569 sys::remove (audio_file_path);
3570 const string peakfile = peak_path (audio_file_path.to_string());
3571 sys::remove (peakfile);
3573 catch (const sys::filesystem_error& err)
3575 error << err.what() << endmsg;
3582 Session::is_auditioning () const
3584 /* can be called before we have an auditioner object */
3586 return auditioner->active();
3593 Session::set_all_solo (bool yn)
3595 shared_ptr<RouteList> r = routes.reader ();
3597 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3598 if (!(*i)->is_hidden()) {
3599 (*i)->set_solo (yn, this);
3607 Session::set_all_listen (bool yn)
3609 shared_ptr<RouteList> r = routes.reader ();
3611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3612 if (!(*i)->is_hidden()) {
3613 (*i)->set_listen (yn, this);
3621 Session::set_all_mute (bool yn)
3623 shared_ptr<RouteList> r = routes.reader ();
3625 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3626 if (!(*i)->is_hidden()) {
3627 (*i)->set_mute (yn, this);
3635 Session::n_diskstreams () const
3639 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3641 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3642 if (!(*i)->hidden()) {
3650 Session::graph_reordered ()
3652 /* don't do this stuff if we are setting up connections
3653 from a set_state() call or creating new tracks.
3656 if (_state_of_the_state & InitialConnecting) {
3660 /* every track/bus asked for this to be handled but it was deferred because
3661 we were connecting. do it now.
3664 request_input_change_handling ();
3668 /* force all diskstreams to update their capture offset values to
3669 reflect any changes in latencies within the graph.
3672 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3674 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3675 (*i)->set_capture_offset ();
3680 Session::record_disenable_all ()
3682 record_enable_change_all (false);
3686 Session::record_enable_all ()
3688 record_enable_change_all (true);
3692 Session::record_enable_change_all (bool yn)
3694 shared_ptr<RouteList> r = routes.reader ();
3696 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3697 boost::shared_ptr<Track> t;
3699 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3700 t->set_record_enable (yn, this);
3704 /* since we don't keep rec-enable state, don't mark session dirty */
3708 Session::add_processor (Processor* processor)
3710 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3715 Session::remove_processor (Processor* processor)
3719 PortInsert* port_insert;
3721 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3722 insert_bitset[port_insert->bit_slot()] = false;
3723 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3724 send_bitset[send->bit_slot()] = false;
3725 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3726 return_bitset[send->bit_slot()] = false;
3733 Session::available_capture_duration ()
3735 float sample_bytes_on_disk = 4.0; // keep gcc happy
3737 switch (config.get_native_file_data_format()) {
3739 sample_bytes_on_disk = 4.0;
3743 sample_bytes_on_disk = 3.0;
3747 sample_bytes_on_disk = 2.0;
3751 /* impossible, but keep some gcc versions happy */
3752 fatal << string_compose (_("programming error: %1"),
3753 X_("illegal native file data format"))
3758 double scale = 4096.0 / sample_bytes_on_disk;
3760 if (_total_free_4k_blocks * scale > (double) max_frames) {
3764 return (nframes_t) floor (_total_free_4k_blocks * scale);
3768 Session::add_bundle (shared_ptr<Bundle> bundle)
3771 RCUWriter<BundleList> writer (_bundles);
3772 boost::shared_ptr<BundleList> b = writer.get_copy ();
3773 b->push_back (bundle);
3776 BundleAdded (bundle); /* EMIT SIGNAL */
3782 Session::remove_bundle (shared_ptr<Bundle> bundle)
3784 bool removed = false;
3787 RCUWriter<BundleList> writer (_bundles);
3788 boost::shared_ptr<BundleList> b = writer.get_copy ();
3789 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3791 if (i != b->end()) {
3798 BundleRemoved (bundle); /* EMIT SIGNAL */
3805 Session::bundle_by_name (string name) const
3807 boost::shared_ptr<BundleList> b = _bundles.reader ();
3809 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3810 if ((*i)->name() == name) {
3815 return boost::shared_ptr<Bundle> ();
3819 Session::tempo_map_changed (Change)
3823 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3824 (*i)->update_after_tempo_map_change ();
3827 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3828 (*i)->update_after_tempo_map_change ();
3834 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3835 * the given count with the current block size.
3838 Session::ensure_buffers (ChanCount howmany)
3840 if (current_block_size == 0) {
3841 return; // too early? (is this ok?)
3844 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3845 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3846 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3847 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3848 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3851 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3855 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3857 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3858 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3863 Session::next_insert_id ()
3865 /* this doesn't really loop forever. just think about it */
3868 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3869 if (!insert_bitset[n]) {
3870 insert_bitset[n] = true;
3876 /* none available, so resize and try again */
3878 insert_bitset.resize (insert_bitset.size() + 16, false);
3883 Session::next_send_id ()
3885 /* this doesn't really loop forever. just think about it */
3888 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3889 if (!send_bitset[n]) {
3890 send_bitset[n] = true;
3896 /* none available, so resize and try again */
3898 send_bitset.resize (send_bitset.size() + 16, false);
3903 Session::next_return_id ()
3905 /* this doesn't really loop forever. just think about it */
3908 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3909 if (!return_bitset[n]) {
3910 return_bitset[n] = true;
3916 /* none available, so resize and try again */
3918 return_bitset.resize (return_bitset.size() + 16, false);
3923 Session::mark_send_id (uint32_t id)
3925 if (id >= send_bitset.size()) {
3926 send_bitset.resize (id+16, false);
3928 if (send_bitset[id]) {
3929 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3931 send_bitset[id] = true;
3935 Session::mark_return_id (uint32_t id)
3937 if (id >= return_bitset.size()) {
3938 return_bitset.resize (id+16, false);
3940 if (return_bitset[id]) {
3941 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3943 return_bitset[id] = true;
3947 Session::mark_insert_id (uint32_t id)
3949 if (id >= insert_bitset.size()) {
3950 insert_bitset.resize (id+16, false);
3952 if (insert_bitset[id]) {
3953 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3955 insert_bitset[id] = true;
3958 /* Named Selection management */
3961 Session::named_selection_by_name (string name)
3963 Glib::Mutex::Lock lm (named_selection_lock);
3964 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3965 if ((*i)->name == name) {
3973 Session::add_named_selection (NamedSelection* named_selection)
3976 Glib::Mutex::Lock lm (named_selection_lock);
3977 named_selections.insert (named_selections.begin(), named_selection);
3980 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3986 NamedSelectionAdded (); /* EMIT SIGNAL */
3990 Session::remove_named_selection (NamedSelection* named_selection)
3992 bool removed = false;
3995 Glib::Mutex::Lock lm (named_selection_lock);
3997 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3999 if (i != named_selections.end()) {
4001 named_selections.erase (i);
4008 NamedSelectionRemoved (); /* EMIT SIGNAL */
4013 Session::reset_native_file_format ()
4015 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4017 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4018 (*i)->reset_write_sources (false);
4023 Session::route_name_unique (string n) const
4025 shared_ptr<RouteList> r = routes.reader ();
4027 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4028 if ((*i)->name() == n) {
4037 Session::route_name_internal (string n) const
4039 if (auditioner && auditioner->name() == n) {
4043 if (_click_io && _click_io->name() == n) {
4051 Session::n_playlists () const
4053 Glib::Mutex::Lock lm (playlist_lock);
4054 return playlists.size();
4058 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4060 if (!force && howmany <= _npan_buffers) {
4064 if (_pan_automation_buffer) {
4066 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4067 delete [] _pan_automation_buffer[i];
4070 delete [] _pan_automation_buffer;
4073 _pan_automation_buffer = new pan_t*[howmany];
4075 for (uint32_t i = 0; i < howmany; ++i) {
4076 _pan_automation_buffer[i] = new pan_t[nframes];
4079 _npan_buffers = howmany;
4083 Session::freeze (InterThreadInfo& itt)
4085 shared_ptr<RouteList> r = routes.reader ();
4087 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4089 boost::shared_ptr<Track> t;
4091 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4092 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4102 boost::shared_ptr<Region>
4103 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4104 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4105 InterThreadInfo& itt, bool enable_processing)
4107 boost::shared_ptr<Region> result;
4108 boost::shared_ptr<Playlist> playlist;
4109 boost::shared_ptr<AudioFileSource> fsource;
4111 char buf[PATH_MAX+1];
4112 ChanCount nchans(track.audio_diskstream()->n_channels());
4114 nframes_t this_chunk;
4117 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4118 const string sound_dir = sdir.sound_path().to_string();
4119 nframes_t len = end - start;
4122 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4123 end, start) << endmsg;
4127 // any bigger than this seems to cause stack overflows in called functions
4128 const nframes_t chunk_size = (128 * 1024)/4;
4130 // block all process callback handling
4132 block_processing ();
4134 /* call tree *MUST* hold route_lock */
4136 if ((playlist = track.diskstream()->playlist()) == 0) {
4140 /* external redirects will be a problem */
4142 if (track.has_external_redirects()) {
4146 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4148 for (x = 0; x < 99999; ++x) {
4149 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4150 if (access (buf, F_OK) != 0) {
4156 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4161 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4162 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4165 catch (failed_constructor& err) {
4166 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4170 srcs.push_back (fsource);
4173 /* XXX need to flush all redirects */
4178 /* create a set of reasonably-sized buffers */
4179 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4180 buffers.set_count(nchans);
4182 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4183 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4185 afs->prepare_for_peakfile_writes ();
4188 while (to_do && !itt.cancel) {
4190 this_chunk = min (to_do, chunk_size);
4192 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4197 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4198 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4201 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4207 start += this_chunk;
4208 to_do -= this_chunk;
4210 itt.progress = (float) (1.0 - ((double) to_do / len));
4219 xnow = localtime (&now);
4221 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4222 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4225 afs->update_header (position, *xnow, now);
4226 afs->flush_header ();
4230 /* construct a region to represent the bounced material */
4232 result = RegionFactory::create (srcs, 0,
4233 srcs.front()->length(srcs.front()->timeline_position()),
4234 region_name_from_path (srcs.front()->name(), true));
4239 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4240 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4243 afs->mark_for_remove ();
4246 (*src)->drop_references ();
4250 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4251 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4254 afs->done_with_peakfile_writes ();
4258 unblock_processing ();
4264 Session::get_silent_buffers (ChanCount count)
4266 assert(_silent_buffers->available() >= count);
4267 _silent_buffers->set_count(count);
4269 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4270 for (size_t i= 0; i < count.get(*t); ++i) {
4271 _silent_buffers->get(*t, i).clear();
4275 return *_silent_buffers;
4279 Session::get_scratch_buffers (ChanCount count)
4281 if (count != ChanCount::ZERO) {
4282 assert(_scratch_buffers->available() >= count);
4283 _scratch_buffers->set_count(count);
4285 _scratch_buffers->set_count (_scratch_buffers->available());
4288 return *_scratch_buffers;
4292 Session::get_mix_buffers (ChanCount count)
4294 assert(_mix_buffers->available() >= count);
4295 _mix_buffers->set_count(count);
4296 return *_mix_buffers;
4300 Session::ntracks () const
4303 shared_ptr<RouteList> r = routes.reader ();
4305 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4306 if (boost::dynamic_pointer_cast<Track> (*i)) {
4315 Session::nbusses () const
4318 shared_ptr<RouteList> r = routes.reader ();
4320 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4321 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4330 Session::add_automation_list(AutomationList *al)
4332 automation_lists[al->id()] = al;
4336 Session::compute_initial_length ()
4338 return _engine.frame_rate() * 60 * 5;
4342 Session::sync_order_keys (std::string const & base)
4344 if (!Config->get_sync_all_route_ordering()) {
4345 /* leave order keys as they are */
4349 boost::shared_ptr<RouteList> r = routes.reader ();
4351 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4352 (*i)->sync_order_keys (base);
4355 Route::SyncOrderKeys (base); // EMIT SIGNAL
4359 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4361 Session::have_rec_enabled_diskstream () const
4363 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4366 /** Update the state of our rec-enabled diskstreams flag */
4368 Session::update_have_rec_enabled_diskstream ()
4370 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4371 DiskstreamList::iterator i = dsl->begin ();
4372 while (i != dsl->end () && (*i)->record_enabled () == false) {
4376 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4378 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4380 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4381 RecordStateChanged (); /* EMIT SIGNAL */
4386 Session::listen_position_changed ()
4390 switch (Config->get_listen_position()) {
4391 case AfterFaderListen:
4395 case PreFaderListen:
4400 boost::shared_ptr<RouteList> r = routes.reader ();
4402 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4403 (*i)->put_control_outs_at (p);
4408 Session::solo_control_mode_changed ()
4410 /* cancel all solo or all listen when solo control mode changes */
4412 if (Config->get_solo_control_is_listen_control()) {
4413 set_all_solo (false);
4415 set_all_listen (false);
4420 Session::route_group_changed ()
4422 RouteGroupChanged (); /* EMIT SIGNAL */