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/butler.h"
60 #include "ardour/click.h"
61 #include "ardour/configuration.h"
62 #include "ardour/crossfade.h"
63 #include "ardour/cycle_timer.h"
64 #include "ardour/data_type.h"
65 #include "ardour/filename_extensions.h"
66 #include "ardour/internal_send.h"
67 #include "ardour/io_processor.h"
68 #include "ardour/midi_diskstream.h"
69 #include "ardour/midi_playlist.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/midi_track.h"
72 #include "ardour/named_selection.h"
73 #include "ardour/playlist.h"
74 #include "ardour/plugin_insert.h"
75 #include "ardour/port_insert.h"
76 #include "ardour/processor.h"
77 #include "ardour/rc_configuration.h"
78 #include "ardour/recent_sessions.h"
79 #include "ardour/region_factory.h"
80 #include "ardour/return.h"
81 #include "ardour/route_group.h"
82 #include "ardour/send.h"
83 #include "ardour/session.h"
84 #include "ardour/session_directory.h"
85 #include "ardour/session_directory.h"
86 #include "ardour/session_metadata.h"
87 #include "ardour/slave.h"
88 #include "ardour/smf_source.h"
89 #include "ardour/source_factory.h"
90 #include "ardour/tape_file_matcher.h"
91 #include "ardour/tempo.h"
92 #include "ardour/utils.h"
97 using namespace ARDOUR;
99 using boost::shared_ptr;
101 bool Session::_disable_all_loaded_plugins = false;
103 sigc::signal<void,std::string> Session::Dialog;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
106 sigc::signal<void> Session::SendFeedback;
108 sigc::signal<void> Session::TimecodeOffsetChanged;
109 sigc::signal<void> Session::StartTimeChanged;
110 sigc::signal<void> Session::EndTimeChanged;
111 sigc::signal<void> Session::AutoBindingOn;
112 sigc::signal<void> Session::AutoBindingOff;
113 sigc::signal<void, std::string, std::string> Session::Exported;
115 Session::Session (AudioEngine &eng,
116 const string& fullpath,
117 const string& snapshot_name,
121 _target_transport_speed (0.0),
122 _requested_return_frame (-1),
123 _scratch_buffers(new BufferSet()),
124 _silent_buffers(new BufferSet()),
125 _mix_buffers(new BufferSet()),
127 _mmc_port (default_mmc_port),
128 _mtc_port (default_mtc_port),
129 _midi_port (default_midi_port),
130 _midi_clock_port (default_midi_clock_port),
131 _session_dir (new SessionDirectory(fullpath)),
132 pending_events (2048),
134 _butler (new Butler (this)),
135 _post_transport_work (0),
136 _send_timecode_update (false),
137 midi_thread (pthread_t (0)),
138 midi_requests (128), // the size of this should match the midi request pool size
139 diskstreams (new DiskstreamList),
140 routes (new RouteList),
141 _total_free_4k_blocks (0),
142 _bundles (new BundleList),
143 _bundle_xml_node (0),
146 click_emphasis_data (0),
148 _metadata (new SessionMetadata()),
149 _have_rec_enabled_diskstream (false)
154 interpolation.add_channel_to (0, 0);
156 if (!eng.connected()) {
157 throw failed_constructor();
160 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
162 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
163 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
165 first_stage_init (fullpath, snapshot_name);
167 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
170 if (create (new_session, mix_template, compute_initial_length())) {
172 throw failed_constructor ();
176 if (second_stage_init (new_session)) {
178 throw failed_constructor ();
181 store_recent_sessions(_name, _path);
183 bool was_dirty = dirty();
185 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
187 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
188 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
191 DirtyChanged (); /* EMIT SIGNAL */
195 Session::Session (AudioEngine &eng,
197 string snapshot_name,
198 AutoConnectOption input_ac,
199 AutoConnectOption output_ac,
200 uint32_t control_out_channels,
201 uint32_t master_out_channels,
202 uint32_t requested_physical_in,
203 uint32_t requested_physical_out,
204 nframes_t initial_length)
207 _target_transport_speed (0.0),
208 _requested_return_frame (-1),
209 _scratch_buffers(new BufferSet()),
210 _silent_buffers(new BufferSet()),
211 _mix_buffers(new BufferSet()),
213 _mmc_port (default_mmc_port),
214 _mtc_port (default_mtc_port),
215 _midi_port (default_midi_port),
216 _midi_clock_port (default_midi_clock_port),
217 _session_dir ( new SessionDirectory(fullpath)),
218 pending_events (2048),
220 _butler (new Butler (this)),
221 _post_transport_work (0),
222 _send_timecode_update (false),
223 midi_thread (pthread_t (0)),
225 diskstreams (new DiskstreamList),
226 routes (new RouteList),
227 _total_free_4k_blocks (0),
228 _bundles (new BundleList),
229 _bundle_xml_node (0),
230 _click_io ((IO *) 0),
232 click_emphasis_data (0),
234 _metadata (new SessionMetadata()),
235 _have_rec_enabled_diskstream (false)
239 interpolation.add_channel_to (0, 0);
241 if (!eng.connected()) {
242 throw failed_constructor();
245 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
247 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
248 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
250 if (n_physical_inputs) {
251 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
254 if (n_physical_outputs) {
255 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
258 first_stage_init (fullpath, snapshot_name);
260 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
263 if (create (new_session, string(), initial_length)) {
265 throw failed_constructor ();
270 /* set up Master Out and Control Out if necessary */
275 if (master_out_channels) {
276 ChanCount count(DataType::AUDIO, master_out_channels);
277 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
278 r->input()->ensure_io (count, false, this);
279 r->output()->ensure_io (count, false, this);
280 r->set_remote_control_id (control_id);
284 /* prohibit auto-connect to master, because there isn't one */
285 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
288 if (control_out_channels) {
289 ChanCount count(DataType::AUDIO, control_out_channels);
290 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
291 r->input()->ensure_io (count, false, this);
292 r->output()->ensure_io (count, false, this);
293 r->set_remote_control_id (control_id++);
299 add_routes (rl, false);
304 if (no_auto_connect()) {
305 input_ac = AutoConnectOption (0);
306 output_ac = AutoConnectOption (0);
309 Config->set_input_auto_connect (input_ac);
310 Config->set_output_auto_connect (output_ac);
312 if (second_stage_init (new_session)) {
314 throw failed_constructor ();
317 store_recent_sessions (_name, _path);
319 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
321 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
332 /* if we got to here, leaving pending capture state around
336 remove_pending_capture_state ();
338 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
340 _engine.remove_session ();
342 GoingAway (); /* EMIT SIGNAL */
348 /* clear history so that no references to objects are held any more */
352 /* clear state tree so that no references to objects are held any more */
356 /* reset dynamic state version back to default */
358 Stateful::loading_state_version = 0;
360 _butler->terminate_thread ();
361 //terminate_midi_thread ();
363 if (click_data != default_click) {
364 delete [] click_data;
367 if (click_emphasis_data != default_click_emphasis) {
368 delete [] click_emphasis_data;
373 delete _scratch_buffers;
374 delete _silent_buffers;
377 AudioDiskstream::free_working_buffers();
379 Route::SyncOrderKeys.clear();
381 #undef TRACK_DESTRUCTION
382 #ifdef TRACK_DESTRUCTION
383 cerr << "delete named selections\n";
384 #endif /* TRACK_DESTRUCTION */
385 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
386 NamedSelectionList::iterator tmp;
395 #ifdef TRACK_DESTRUCTION
396 cerr << "delete playlists\n";
397 #endif /* TRACK_DESTRUCTION */
398 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
399 PlaylistList::iterator tmp;
404 (*i)->drop_references ();
409 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
410 PlaylistList::iterator tmp;
415 (*i)->drop_references ();
421 unused_playlists.clear ();
423 #ifdef TRACK_DESTRUCTION
424 cerr << "delete regions\n";
425 #endif /* TRACK_DESTRUCTION */
427 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
428 RegionList::iterator tmp;
433 i->second->drop_references ();
440 #ifdef TRACK_DESTRUCTION
441 cerr << "delete routes\n";
442 #endif /* TRACK_DESTRUCTION */
444 RCUWriter<RouteList> writer (routes);
445 boost::shared_ptr<RouteList> r = writer.get_copy ();
446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
447 (*i)->drop_references ();
450 /* writer goes out of scope and updates master */
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete diskstreams\n";
457 #endif /* TRACK_DESTRUCTION */
459 RCUWriter<DiskstreamList> dwriter (diskstreams);
460 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
461 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
462 (*i)->drop_references ();
466 diskstreams.flush ();
468 #ifdef TRACK_DESTRUCTION
469 cerr << "delete audio sources\n";
470 #endif /* TRACK_DESTRUCTION */
471 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
472 SourceMap::iterator tmp;
477 i->second->drop_references ();
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete route groups\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
491 Crossfade::set_buffer_size (0);
497 Session::set_worst_io_latencies ()
499 _worst_output_latency = 0;
500 _worst_input_latency = 0;
502 if (!_engine.connected()) {
506 boost::shared_ptr<RouteList> r = routes.reader ();
508 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
509 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
510 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
515 Session::when_engine_running ()
517 string first_physical_output;
519 BootMessage (_("Set block size and sample rate"));
521 set_block_size (_engine.frames_per_cycle());
522 set_frame_rate (_engine.frame_rate());
524 BootMessage (_("Using configuration"));
526 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
528 /* every time we reconnect, recompute worst case output latencies */
530 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
532 if (synced_to_jack()) {
533 _engine.transport_stop ();
536 if (config.get_jack_time_master()) {
537 _engine.transport_locate (_transport_frame);
545 _click_io.reset (new ClickIO (*this, "click"));
547 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
549 /* existing state for Click */
552 if (Stateful::loading_state_version < 3000) {
553 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
555 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
560 _clicking = Config->get_clicking ();
564 error << _("could not setup Click I/O") << endmsg;
571 /* default state for Click: dual-mono to first 2 physical outputs */
573 for (int physport = 0; physport < 2; ++physport) {
574 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
576 if (physical_output.length()) {
577 if (_click_io->add_port (physical_output, this)) {
578 // relax, even though its an error
583 if (_click_io->n_ports () > ChanCount::ZERO) {
584 _clicking = Config->get_clicking ();
589 catch (failed_constructor& err) {
590 error << _("cannot setup Click I/O") << endmsg;
593 BootMessage (_("Compute I/O Latencies"));
595 set_worst_io_latencies ();
598 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
601 BootMessage (_("Set up standard connections"));
603 /* Create a set of Bundle objects that map
604 to the physical I/O currently available. We create both
605 mono and stereo bundles, so that the common cases of mono
606 and stereo tracks get bundles to put in their mixer strip
607 in / out menus. There may be a nicer way of achieving that;
608 it doesn't really scale that well to higher channel counts
611 /* mono output bundles */
613 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
615 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
617 shared_ptr<Bundle> c (new Bundle (buf, true));
618 c->add_channel (_("mono"));
619 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
624 /* stereo output bundles */
626 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
627 if (np + 1 < n_physical_outputs) {
629 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
630 shared_ptr<Bundle> c (new Bundle (buf, true));
631 c->add_channel (_("L"));
632 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
633 c->add_channel (_("R"));
634 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
640 /* mono input bundles */
642 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
644 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
646 shared_ptr<Bundle> c (new Bundle (buf, false));
647 c->add_channel (_("mono"));
648 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
653 /* stereo input bundles */
655 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
656 if (np + 1 < n_physical_inputs) {
658 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
660 shared_ptr<Bundle> c (new Bundle (buf, false));
661 c->add_channel (_("L"));
662 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
663 c->add_channel (_("R"));
664 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
670 BootMessage (_("Setup signal flow and plugins"));
674 if (!no_auto_connect()) {
676 if (_master_out && Config->get_auto_connect_standard_busses()) {
678 /* if requested auto-connect the outputs to the first N physical ports.
681 uint32_t limit = _master_out->n_outputs().n_total();
683 for (uint32_t n = 0; n < limit; ++n) {
684 Port* p = _master_out->output()->nth (n);
685 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
687 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
688 if (_master_out->output()->connect (p, connect_to, this)) {
689 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
699 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
700 are undefined, at best.
703 /* control out listens to master bus (but ignores it
704 under some conditions)
707 uint32_t limit = _control_out->n_inputs().n_audio();
710 for (uint32_t n = 0; n < limit; ++n) {
711 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
712 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
715 string connect_to = o->name();
716 if (_control_out->input()->connect (p, connect_to, this)) {
717 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
725 /* if control out is not connected,
726 connect control out to physical outs, but use ones after the master if possible
729 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
731 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
733 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
736 _control_out->output()->connect_ports_to_bundle (b, this);
738 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
739 Config->get_monitor_bus_preferred_bundle())
745 /* XXX this logic is wrong for mixed port types */
747 uint32_t shift = _master_out->n_outputs().n_audio();
748 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
749 limit = _control_out->n_outputs().n_audio();
751 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
753 for (uint32_t n = 0; n < limit; ++n) {
755 Port* p = _control_out->output()->nth (n);
756 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
758 if (!connect_to.empty()) {
759 if (_control_out->output()->connect (p, connect_to, this)) {
760 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
771 /* catch up on send+insert cnts */
773 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
775 /* hook us up to the engine */
777 BootMessage (_("Connect to engine"));
779 _engine.set_session (this);
783 Session::hookup_io ()
785 /* stop graph reordering notifications from
786 causing resorts, etc.
789 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
794 /* we delay creating the auditioner till now because
795 it makes its own connections to ports.
796 the engine has to be running for this to work.
800 auditioner.reset (new Auditioner (*this));
803 catch (failed_constructor& err) {
804 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
808 /* load bundles, which we may have postponed earlier on */
809 if (_bundle_xml_node) {
810 load_bundles (*_bundle_xml_node);
811 delete _bundle_xml_node;
814 /* Tell all IO objects to connect themselves together */
816 IO::enable_connecting ();
818 /* Now reset all panners */
820 Delivery::reset_panners ();
822 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
826 boost::shared_ptr<RouteList> r = routes.reader ();
828 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
830 if ((*x)->is_control() || (*x)->is_master()) {
834 (*x)->listen_via (_control_out,
835 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
840 /* Anyone who cares about input state, wake up and do something */
842 IOConnectionsComplete (); /* EMIT SIGNAL */
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
846 /* now handle the whole enchilada as if it was one
852 /* update the full solo state, which can't be
853 correctly determined on a per-route basis, but
854 needs the global overview that only the session
858 update_route_solo_state ();
862 Session::playlist_length_changed ()
864 /* we can't just increase end_location->end() if pl->get_maximum_extent()
865 if larger. if the playlist used to be the longest playlist,
866 and its now shorter, we have to decrease end_location->end(). hence,
867 we have to iterate over all diskstreams and check the
868 playlists currently in use.
874 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
876 boost::shared_ptr<Diskstream> dstream = wp.lock ();
881 boost::shared_ptr<Playlist> playlist;
883 if ((playlist = dstream->playlist()) != 0) {
884 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
887 /* see comment in playlist_length_changed () */
892 Session::record_enabling_legal () const
894 /* this used to be in here, but survey says.... we don't need to restrict it */
895 // if (record_status() == Recording) {
899 if (Config->get_all_safe()) {
906 Session::reset_input_monitor_state ()
908 if (transport_rolling()) {
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 = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
915 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
919 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
921 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
922 if ((*i)->record_enabled ()) {
923 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
924 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
931 Session::auto_punch_start_changed (Location* location)
933 replace_event (Event::PunchIn, location->start());
935 if (get_record_enabled() && config.get_punch_in()) {
936 /* capture start has been changed, so save new pending state */
937 save_state ("", true);
942 Session::auto_punch_end_changed (Location* location)
944 nframes_t when_to_stop = location->end();
945 // when_to_stop += _worst_output_latency + _worst_input_latency;
946 replace_event (Event::PunchOut, when_to_stop);
950 Session::auto_punch_changed (Location* location)
952 nframes_t when_to_stop = location->end();
954 replace_event (Event::PunchIn, location->start());
955 //when_to_stop += _worst_output_latency + _worst_input_latency;
956 replace_event (Event::PunchOut, when_to_stop);
960 Session::auto_loop_changed (Location* location)
962 replace_event (Event::AutoLoop, location->end(), location->start());
964 if (transport_rolling() && play_loop) {
967 // if (_transport_frame > location->end()) {
969 if (_transport_frame < location->start() || _transport_frame > location->end()) {
970 // relocate to beginning of loop
971 clear_events (Event::LocateRoll);
973 request_locate (location->start(), true);
976 else if (Config->get_seamless_loop() && !loop_changing) {
978 // schedule a locate-roll to refill the diskstreams at the
980 loop_changing = true;
982 if (location->end() > last_loopend) {
983 clear_events (Event::LocateRoll);
984 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
991 last_loopend = location->end();
995 Session::set_auto_punch_location (Location* location)
999 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1000 auto_punch_start_changed_connection.disconnect();
1001 auto_punch_end_changed_connection.disconnect();
1002 auto_punch_changed_connection.disconnect();
1003 existing->set_auto_punch (false, this);
1004 remove_event (existing->start(), Event::PunchIn);
1005 clear_events (Event::PunchOut);
1006 auto_punch_location_changed (0);
1011 if (location == 0) {
1015 if (location->end() <= location->start()) {
1016 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1020 auto_punch_start_changed_connection.disconnect();
1021 auto_punch_end_changed_connection.disconnect();
1022 auto_punch_changed_connection.disconnect();
1024 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1025 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1026 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1028 location->set_auto_punch (true, this);
1031 auto_punch_changed (location);
1033 auto_punch_location_changed (location);
1037 Session::set_auto_loop_location (Location* location)
1041 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1042 auto_loop_start_changed_connection.disconnect();
1043 auto_loop_end_changed_connection.disconnect();
1044 auto_loop_changed_connection.disconnect();
1045 existing->set_auto_loop (false, this);
1046 remove_event (existing->end(), Event::AutoLoop);
1047 auto_loop_location_changed (0);
1052 if (location == 0) {
1056 if (location->end() <= location->start()) {
1057 error << _("Session: you can't use a mark for auto loop") << endmsg;
1061 last_loopend = location->end();
1063 auto_loop_start_changed_connection.disconnect();
1064 auto_loop_end_changed_connection.disconnect();
1065 auto_loop_changed_connection.disconnect();
1067 auto_loop_start_changed_connection = location->start_changed.connect (
1068 mem_fun (this, &Session::auto_loop_changed));
1069 auto_loop_end_changed_connection = location->end_changed.connect (
1070 mem_fun (this, &Session::auto_loop_changed));
1071 auto_loop_changed_connection = location->changed.connect (
1072 mem_fun (this, &Session::auto_loop_changed));
1074 location->set_auto_loop (true, this);
1076 /* take care of our stuff first */
1078 auto_loop_changed (location);
1080 /* now tell everyone else */
1082 auto_loop_location_changed (location);
1086 Session::locations_added (Location *)
1092 Session::locations_changed ()
1094 _locations.apply (*this, &Session::handle_locations_changed);
1098 Session::handle_locations_changed (Locations::LocationList& locations)
1100 Locations::LocationList::iterator i;
1102 bool set_loop = false;
1103 bool set_punch = false;
1105 for (i = locations.begin(); i != locations.end(); ++i) {
1109 if (location->is_auto_punch()) {
1110 set_auto_punch_location (location);
1113 if (location->is_auto_loop()) {
1114 set_auto_loop_location (location);
1118 if (location->is_start()) {
1119 start_location = location;
1121 if (location->is_end()) {
1122 end_location = location;
1127 set_auto_loop_location (0);
1130 set_auto_punch_location (0);
1137 Session::enable_record ()
1139 /* XXX really atomic compare+swap here */
1140 if (g_atomic_int_get (&_record_status) != Recording) {
1141 g_atomic_int_set (&_record_status, Recording);
1142 _last_record_location = _transport_frame;
1143 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1145 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1146 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1147 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1148 if ((*i)->record_enabled ()) {
1149 (*i)->monitor_input (true);
1154 RecordStateChanged ();
1159 Session::disable_record (bool rt_context, bool force)
1163 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1165 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1166 g_atomic_int_set (&_record_status, Disabled);
1168 if (rs == Recording) {
1169 g_atomic_int_set (&_record_status, Enabled);
1173 // FIXME: timestamp correct? [DR]
1174 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1175 // does this /need/ to be sent in all cases?
1177 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1179 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1180 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1182 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1183 if ((*i)->record_enabled ()) {
1184 (*i)->monitor_input (false);
1189 RecordStateChanged (); /* emit signal */
1192 remove_pending_capture_state ();
1198 Session::step_back_from_record ()
1200 /* XXX really atomic compare+swap here */
1201 if (g_atomic_int_get (&_record_status) == Recording) {
1202 g_atomic_int_set (&_record_status, Enabled);
1204 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1205 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1207 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1208 if ((*i)->record_enabled ()) {
1209 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1210 (*i)->monitor_input (false);
1218 Session::maybe_enable_record ()
1220 g_atomic_int_set (&_record_status, Enabled);
1222 /* this function is currently called from somewhere other than an RT thread.
1223 this save_state() call therefore doesn't impact anything.
1226 save_state ("", true);
1228 if (_transport_speed) {
1229 if (!config.get_punch_in()) {
1233 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1234 RecordStateChanged (); /* EMIT SIGNAL */
1241 Session::audible_frame () const
1247 /* the first of these two possible settings for "offset"
1248 mean that the audible frame is stationary until
1249 audio emerges from the latency compensation
1252 the second means that the audible frame is stationary
1253 until audio would emerge from a physical port
1254 in the absence of any plugin latency compensation
1257 offset = _worst_output_latency;
1259 if (offset > current_block_size) {
1260 offset -= current_block_size;
1262 /* XXX is this correct? if we have no external
1263 physical connections and everything is internal
1264 then surely this is zero? still, how
1265 likely is that anyway?
1267 offset = current_block_size;
1270 if (synced_to_jack()) {
1271 tf = _engine.transport_frame();
1273 tf = _transport_frame;
1278 if (!non_realtime_work_pending()) {
1282 /* check to see if we have passed the first guaranteed
1283 audible frame past our last start position. if not,
1284 return that last start point because in terms
1285 of audible frames, we have not moved yet.
1288 if (_transport_speed > 0.0f) {
1290 if (!play_loop || !have_looped) {
1291 if (tf < _last_roll_location + offset) {
1292 return _last_roll_location;
1300 } else if (_transport_speed < 0.0f) {
1302 /* XXX wot? no backward looping? */
1304 if (tf > _last_roll_location - offset) {
1305 return _last_roll_location;
1317 Session::set_frame_rate (nframes_t frames_per_second)
1319 /** \fn void Session::set_frame_size(nframes_t)
1320 the AudioEngine object that calls this guarantees
1321 that it will not be called while we are also in
1322 ::process(). Its fine to do things that block
1326 _base_frame_rate = frames_per_second;
1330 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1334 // XXX we need some equivalent to this, somehow
1335 // SndFileSource::setup_standard_crossfades (frames_per_second);
1339 /* XXX need to reset/reinstantiate all LADSPA plugins */
1343 Session::set_block_size (nframes_t nframes)
1345 /* the AudioEngine guarantees
1346 that it will not be called while we are also in
1347 ::process(). It is therefore fine to do things that block
1352 current_block_size = nframes;
1354 ensure_buffers(_scratch_buffers->available());
1356 delete [] _gain_automation_buffer;
1357 _gain_automation_buffer = new gain_t[nframes];
1359 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1361 boost::shared_ptr<RouteList> r = routes.reader ();
1363 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1364 (*i)->set_block_size (nframes);
1367 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1368 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1369 (*i)->set_block_size (nframes);
1372 set_worst_io_latencies ();
1377 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1380 nframes_t fade_frames;
1382 /* Don't allow fade of less 1 frame */
1384 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1391 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1395 default_fade_msecs = fade_msecs;
1396 default_fade_steepness = steepness;
1399 // jlc, WTF is this!
1400 Glib::RWLock::ReaderLock lm (route_lock);
1401 AudioRegion::set_default_fade (steepness, fade_frames);
1406 /* XXX have to do this at some point */
1407 /* foreach region using default fade, reset, then
1408 refill_all_diskstream_buffers ();
1413 struct RouteSorter {
1414 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1415 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1417 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1420 if (r1->fed_by.empty()) {
1421 if (r2->fed_by.empty()) {
1422 /* no ardour-based connections inbound to either route. just use signal order */
1423 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1425 /* r2 has connections, r1 does not; run r1 early */
1429 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1436 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1438 shared_ptr<Route> r2;
1440 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1441 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1445 /* make a copy of the existing list of routes that feed r1 */
1447 set<shared_ptr<Route> > existing = r1->fed_by;
1449 /* for each route that feeds r1, recurse, marking it as feeding
1453 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1456 /* r2 is a route that feeds r1 which somehow feeds base. mark
1457 base as being fed by r2
1460 rbase->fed_by.insert (r2);
1464 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1468 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1472 /* now recurse, so that we can mark base as being fed by
1473 all routes that feed r2
1476 trace_terminal (r2, rbase);
1483 Session::resort_routes ()
1485 /* don't do anything here with signals emitted
1486 by Routes while we are being destroyed.
1489 if (_state_of_the_state & Deletion) {
1496 RCUWriter<RouteList> writer (routes);
1497 shared_ptr<RouteList> r = writer.get_copy ();
1498 resort_routes_using (r);
1499 /* writer goes out of scope and forces update */
1504 Session::resort_routes_using (shared_ptr<RouteList> r)
1506 RouteList::iterator i, j;
1508 for (i = r->begin(); i != r->end(); ++i) {
1510 (*i)->fed_by.clear ();
1512 for (j = r->begin(); j != r->end(); ++j) {
1514 /* although routes can feed themselves, it will
1515 cause an endless recursive descent if we
1516 detect it. so don't bother checking for
1524 if ((*j)->feeds (*i)) {
1525 (*i)->fed_by.insert (*j);
1530 for (i = r->begin(); i != r->end(); ++i) {
1531 trace_terminal (*i, *i);
1538 cerr << "finished route resort\n";
1540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1541 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1548 list<boost::shared_ptr<MidiTrack> >
1549 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1551 char track_name[32];
1552 uint32_t track_id = 0;
1555 RouteList new_routes;
1556 list<boost::shared_ptr<MidiTrack> > ret;
1557 //uint32_t control_id;
1559 // FIXME: need physical I/O and autoconnect stuff for MIDI
1561 /* count existing midi tracks */
1564 shared_ptr<RouteList> r = routes.reader ();
1566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1567 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1568 if (!(*i)->is_hidden()) {
1570 //channels_used += (*i)->n_inputs().n_midi();
1576 vector<string> physinputs;
1577 vector<string> physoutputs;
1579 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1580 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1582 // control_id = ntracks() + nbusses();
1586 /* check for duplicate route names, since we might have pre-existing
1587 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1588 save, close,restart,add new route - first named route is now
1596 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1598 if (route_by_name (track_name) == 0) {
1602 } while (track_id < (UINT_MAX-1));
1604 shared_ptr<MidiTrack> track;
1607 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1609 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1610 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1615 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1616 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1622 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1626 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1627 port = physinputs[(channels_used+x)%nphysical_in];
1630 if (port.length() && track->connect_input (track->input (x), port, this)) {
1636 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1640 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1641 port = physoutputs[(channels_used+x)%nphysical_out];
1642 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1644 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1648 if (port.length() && track->connect_output (track->output (x), port, this)) {
1653 channels_used += track->n_inputs ().n_midi();
1657 track->midi_diskstream()->non_realtime_input_change();
1658 track->set_route_group (route_group, 0);
1660 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1661 //track->set_remote_control_id (control_id);
1663 new_routes.push_back (track);
1664 ret.push_back (track);
1667 catch (failed_constructor &err) {
1668 error << _("Session: could not create new midi track.") << endmsg;
1671 /* we need to get rid of this, since the track failed to be created */
1672 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1675 RCUWriter<DiskstreamList> writer (diskstreams);
1676 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1677 ds->remove (track->midi_diskstream());
1684 catch (AudioEngine::PortRegistrationFailure& pfe) {
1686 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;
1689 /* we need to get rid of this, since the track failed to be created */
1690 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1693 RCUWriter<DiskstreamList> writer (diskstreams);
1694 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1695 ds->remove (track->midi_diskstream());
1706 if (!new_routes.empty()) {
1707 add_routes (new_routes, false);
1708 save_state (_current_snapshot_name);
1714 list<boost::shared_ptr<AudioTrack> >
1715 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1717 char track_name[32];
1718 uint32_t track_id = 0;
1720 uint32_t channels_used = 0;
1722 RouteList new_routes;
1723 list<boost::shared_ptr<AudioTrack> > ret;
1724 uint32_t control_id;
1726 /* count existing audio tracks */
1729 shared_ptr<RouteList> r = routes.reader ();
1731 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1732 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1733 if (!(*i)->is_hidden()) {
1735 channels_used += (*i)->n_inputs().n_audio();
1741 vector<string> physinputs;
1742 vector<string> physoutputs;
1744 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1745 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1747 control_id = ntracks() + nbusses() + 1;
1751 /* check for duplicate route names, since we might have pre-existing
1752 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1753 save, close,restart,add new route - first named route is now
1761 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1763 if (route_by_name (track_name) == 0) {
1767 } while (track_id < (UINT_MAX-1));
1769 shared_ptr<AudioTrack> track;
1772 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1774 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1775 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1776 input_channels, output_channels)
1781 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1788 if (!physinputs.empty()) {
1789 uint32_t nphysical_in = physinputs.size();
1791 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1795 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1796 port = physinputs[(channels_used+x)%nphysical_in];
1799 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1805 if (!physoutputs.empty()) {
1806 uint32_t nphysical_out = physoutputs.size();
1808 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1811 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1812 port = physoutputs[(channels_used+x)%nphysical_out];
1813 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1814 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1815 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1819 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1825 channels_used += track->n_inputs ().n_audio();
1827 track->set_route_group (route_group, 0);
1829 track->audio_diskstream()->non_realtime_input_change();
1831 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1832 track->set_remote_control_id (control_id);
1835 new_routes.push_back (track);
1836 ret.push_back (track);
1839 catch (failed_constructor &err) {
1840 error << _("Session: could not create new audio track.") << endmsg;
1843 /* we need to get rid of this, since the track failed to be created */
1844 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1847 RCUWriter<DiskstreamList> writer (diskstreams);
1848 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1849 ds->remove (track->audio_diskstream());
1856 catch (AudioEngine::PortRegistrationFailure& pfe) {
1858 error << pfe.what() << endmsg;
1861 /* we need to get rid of this, since the track failed to be created */
1862 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1865 RCUWriter<DiskstreamList> writer (diskstreams);
1866 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1867 ds->remove (track->audio_diskstream());
1878 if (!new_routes.empty()) {
1879 add_routes (new_routes, true);
1886 Session::set_remote_control_ids ()
1888 RemoteModel m = Config->get_remote_model();
1890 shared_ptr<RouteList> r = routes.reader ();
1892 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1893 if ( MixerOrdered == m) {
1894 long order = (*i)->order_key(N_("signal"));
1895 (*i)->set_remote_control_id( order+1 );
1896 } else if ( EditorOrdered == m) {
1897 long order = (*i)->order_key(N_("editor"));
1898 (*i)->set_remote_control_id( order+1 );
1899 } else if ( UserOrdered == m) {
1900 //do nothing ... only changes to remote id's are initiated by user
1907 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1910 uint32_t bus_id = 1;
1912 uint32_t channels_used = 0;
1915 uint32_t control_id;
1917 /* count existing audio busses */
1920 shared_ptr<RouteList> r = routes.reader ();
1922 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1923 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1925 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1928 channels_used += (*i)->n_inputs().n_audio();
1934 vector<string> physinputs;
1935 vector<string> physoutputs;
1937 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1938 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1940 n_physical_audio_outputs = physoutputs.size();
1941 n_physical_audio_inputs = physinputs.size();
1943 control_id = ntracks() + nbusses() + 1;
1948 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1952 if (route_by_name (bus_name) == 0) {
1956 } while (bus_id < (UINT_MAX-1));
1959 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1961 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1962 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1963 input_channels, output_channels)
1969 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1970 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1971 input_channels, output_channels)
1976 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1979 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1980 port = physinputs[((n+x)%n_physical_audio_inputs)];
1983 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1988 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1991 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1992 port = physoutputs[((n+x)%n_physical_outputs)];
1993 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1995 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1999 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2004 channels_used += bus->n_inputs ().n_audio();
2006 bus->set_route_group (route_group, 0);
2007 bus->set_remote_control_id (control_id);
2010 ret.push_back (bus);
2014 catch (failed_constructor &err) {
2015 error << _("Session: could not create new audio route.") << endmsg;
2019 catch (AudioEngine::PortRegistrationFailure& pfe) {
2020 error << pfe.what() << endmsg;
2030 add_routes (ret, true);
2038 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2042 uint32_t control_id;
2044 uint32_t number = 1;
2046 if (!tree.read (template_path.c_str())) {
2050 XMLNode* node = tree.root();
2052 control_id = ntracks() + nbusses() + 1;
2056 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2058 std::string node_name = IO::name_from_state (*node_copy.children().front());
2060 /* generate a new name by adding a number to the end of the template name */
2063 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2067 if (route_by_name (name) == 0) {
2071 } while (number < UINT_MAX);
2073 if (number == UINT_MAX) {
2074 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2078 IO::set_name_in_state (*node_copy.children().front(), name);
2080 Track::zero_diskstream_id_in_xml (node_copy);
2083 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2086 error << _("Session: cannot create track/bus from template description") << endmsg;
2090 if (boost::dynamic_pointer_cast<Track>(route)) {
2091 /* force input/output change signals so that the new diskstream
2092 picks up the configuration of the route. During session
2093 loading this normally happens in a different way.
2095 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2096 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2099 route->set_remote_control_id (control_id);
2102 ret.push_back (route);
2105 catch (failed_constructor &err) {
2106 error << _("Session: could not create new route from template") << endmsg;
2110 catch (AudioEngine::PortRegistrationFailure& pfe) {
2111 error << pfe.what() << endmsg;
2120 add_routes (ret, true);
2127 Session::add_routes (RouteList& new_routes, bool save)
2130 RCUWriter<RouteList> writer (routes);
2131 shared_ptr<RouteList> r = writer.get_copy ();
2132 r->insert (r->end(), new_routes.begin(), new_routes.end());
2135 /* if there is no control out and we're not in the middle of loading,
2136 resort the graph here. if there is a control out, we will resort
2137 toward the end of this method. if we are in the middle of loading,
2138 we will resort when done.
2141 if (!_control_out && IO::connecting_legal) {
2142 resort_routes_using (r);
2146 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2148 boost::weak_ptr<Route> wpr (*x);
2150 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2151 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2152 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2153 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2154 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2155 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2157 if ((*x)->is_master()) {
2161 if ((*x)->is_control()) {
2162 _control_out = (*x);
2166 if (_control_out && IO::connecting_legal) {
2168 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2169 if ((*x)->is_control() || (*x)->is_master()) {
2172 (*x)->listen_via (_control_out,
2173 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2183 save_state (_current_snapshot_name);
2186 RouteAdded (new_routes); /* EMIT SIGNAL */
2190 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2192 boost::shared_ptr<RouteList> r = routes.reader ();
2193 boost::shared_ptr<Send> s;
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if (boost::dynamic_pointer_cast<Track>(*i)) {
2199 if ((s = (*i)->internal_send_for (dest)) != 0) {
2200 s->amp()->gain_control()->set_value (0.0);
2207 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2209 boost::shared_ptr<RouteList> r = routes.reader ();
2210 boost::shared_ptr<Send> s;
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2215 if (boost::dynamic_pointer_cast<Track>(*i)) {
2216 if ((s = (*i)->internal_send_for (dest)) != 0) {
2217 s->amp()->gain_control()->set_value (1.0);
2224 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2226 boost::shared_ptr<RouteList> r = routes.reader ();
2227 boost::shared_ptr<Send> s;
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if (boost::dynamic_pointer_cast<Track>(*i)) {
2233 if ((s = (*i)->internal_send_for (dest)) != 0) {
2234 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2241 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2243 boost::shared_ptr<RouteList> r = routes.reader ();
2244 boost::shared_ptr<RouteList> t (new RouteList);
2246 /* only send tracks */
2248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2249 if (boost::dynamic_pointer_cast<Track>(*i)) {
2254 add_internal_sends (dest, p, t);
2259 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2261 if (dest->is_control() || dest->is_master()) {
2265 if (!dest->internal_return()) {
2266 dest->add_internal_return();
2269 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2271 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2275 (*i)->listen_via (dest, p, true, true);
2280 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2282 /* need to do this in case we're rolling at the time, to prevent false underruns */
2283 dstream->do_refill_with_alloc ();
2285 dstream->set_block_size (current_block_size);
2288 RCUWriter<DiskstreamList> writer (diskstreams);
2289 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2290 ds->push_back (dstream);
2291 /* writer goes out of scope, copies ds back to main */
2294 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2295 /* this will connect to future changes, and check the current length */
2296 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2298 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2300 dstream->prepare ();
2305 Session::remove_route (shared_ptr<Route> route)
2308 RCUWriter<RouteList> writer (routes);
2309 shared_ptr<RouteList> rs = writer.get_copy ();
2313 /* deleting the master out seems like a dumb
2314 idea, but its more of a UI policy issue
2318 if (route == _master_out) {
2319 _master_out = shared_ptr<Route> ();
2322 if (route == _control_out) {
2324 /* cancel control outs for all routes */
2326 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2327 (*r)->drop_listen (_control_out);
2330 _control_out.reset ();
2333 update_route_solo_state ();
2335 /* writer goes out of scope, forces route list update */
2338 boost::shared_ptr<Track> t;
2339 boost::shared_ptr<Diskstream> ds;
2341 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2342 ds = t->diskstream();
2348 RCUWriter<DiskstreamList> dsl (diskstreams);
2349 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2354 find_current_end ();
2356 // We need to disconnect the routes inputs and outputs
2358 route->input()->disconnect (0);
2359 route->output()->disconnect (0);
2361 update_latency_compensation (false, false);
2364 /* get rid of it from the dead wood collection in the route list manager */
2366 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2370 /* try to cause everyone to drop their references */
2372 route->drop_references ();
2374 sync_order_keys (N_("session"));
2376 /* save the new state of the world */
2378 if (save_state (_current_snapshot_name)) {
2379 save_history (_current_snapshot_name);
2384 Session::route_mute_changed (void* /*src*/)
2390 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2392 boost::shared_ptr<Route> route = wpr.lock();
2394 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2398 if (route->listening()) {
2400 } else if (_listen_cnt > 0) {
2406 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2408 if (solo_update_disabled) {
2413 boost::shared_ptr<Route> route = wpr.lock ();
2416 /* should not happen */
2417 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2421 shared_ptr<RouteList> r = routes.reader ();
2424 if (route->soloed()) {
2430 /* now mod the solo level of all other routes except master & control outs
2431 so that they will be silent if appropriate.
2434 solo_update_disabled = true;
2435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2436 bool via_sends_only;
2438 if ((*i)->feeds (route, &via_sends_only) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2439 if (!via_sends_only) {
2441 (*i)->mod_solo_level (delta);
2446 /* make sure master is never muted by solo */
2448 if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2449 _master_out->mod_solo_level (1);
2452 /* ditto for control outs make sure master is never muted by solo */
2454 if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
2455 _control_out->mod_solo_level (1);
2458 solo_update_disabled = false;
2459 update_route_solo_state (r);
2460 SoloChanged (); /* EMIT SIGNAL */
2465 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2467 /* now figure out if anything that matters is soloed */
2469 bool something_soloed = false;
2472 r = routes.reader();
2475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2476 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2477 something_soloed = true;
2482 if (something_soloed != _non_soloed_outs_muted) {
2483 _non_soloed_outs_muted = something_soloed;
2484 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2489 Session::route_by_name (string name)
2491 shared_ptr<RouteList> r = routes.reader ();
2493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2494 if ((*i)->name() == name) {
2499 return shared_ptr<Route> ((Route*) 0);
2503 Session::route_by_id (PBD::ID id)
2505 shared_ptr<RouteList> r = routes.reader ();
2507 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2508 if ((*i)->id() == id) {
2513 return shared_ptr<Route> ((Route*) 0);
2517 Session::route_by_remote_id (uint32_t id)
2519 shared_ptr<RouteList> r = routes.reader ();
2521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2522 if ((*i)->remote_control_id() == id) {
2527 return shared_ptr<Route> ((Route*) 0);
2531 Session::find_current_end ()
2533 if (_state_of_the_state & Loading) {
2537 nframes_t max = get_maximum_extent ();
2539 if (max > end_location->end()) {
2540 end_location->set_end (max);
2542 DurationChanged(); /* EMIT SIGNAL */
2547 Session::get_maximum_extent () const
2552 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2554 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2555 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2557 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2558 if ((me = pl->get_maximum_extent()) > max) {
2566 boost::shared_ptr<Diskstream>
2567 Session::diskstream_by_name (string name)
2569 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2571 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2572 if ((*i)->name() == name) {
2577 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2580 boost::shared_ptr<Diskstream>
2581 Session::diskstream_by_id (const PBD::ID& id)
2583 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2585 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2586 if ((*i)->id() == id) {
2591 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2594 /* Region management */
2597 Session::new_region_name (string old)
2599 string::size_type last_period;
2601 string::size_type len = old.length() + 64;
2604 if ((last_period = old.find_last_of ('.')) == string::npos) {
2606 /* no period present - add one explicitly */
2609 last_period = old.length() - 1;
2614 number = atoi (old.substr (last_period+1).c_str());
2618 while (number < (UINT_MAX-1)) {
2620 RegionList::const_iterator i;
2625 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2628 for (i = regions.begin(); i != regions.end(); ++i) {
2629 if (i->second->name() == sbuf) {
2634 if (i == regions.end()) {
2639 if (number != (UINT_MAX-1)) {
2643 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2648 Session::region_name (string& result, string base, bool newlevel)
2653 if (base.find("/") != string::npos) {
2654 base = base.substr(base.find_last_of("/") + 1);
2659 Glib::Mutex::Lock lm (region_lock);
2661 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2670 string::size_type pos;
2672 pos = base.find_last_of ('.');
2674 /* pos may be npos, but then we just use entire base */
2676 subbase = base.substr (0, pos);
2681 Glib::Mutex::Lock lm (region_lock);
2683 map<string,uint32_t>::iterator x;
2687 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2689 region_name_map[subbase] = 1;
2692 snprintf (buf, sizeof (buf), ".%d", x->second);
2703 Session::add_region (boost::shared_ptr<Region> region)
2705 vector<boost::shared_ptr<Region> > v;
2706 v.push_back (region);
2711 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2716 Glib::Mutex::Lock lm (region_lock);
2718 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2720 boost::shared_ptr<Region> region = *ii;
2724 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2728 RegionList::iterator x;
2730 for (x = regions.begin(); x != regions.end(); ++x) {
2732 if (region->region_list_equivalent (x->second)) {
2737 if (x == regions.end()) {
2739 pair<RegionList::key_type,RegionList::mapped_type> entry;
2741 entry.first = region->id();
2742 entry.second = region;
2744 pair<RegionList::iterator,bool> x = regions.insert (entry);
2756 /* mark dirty because something has changed even if we didn't
2757 add the region to the region list.
2764 vector<boost::weak_ptr<Region> > v;
2765 boost::shared_ptr<Region> first_r;
2767 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2769 boost::shared_ptr<Region> region = *ii;
2773 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2776 v.push_back (region);
2783 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2784 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2786 update_region_name_map (region);
2790 RegionsAdded (v); /* EMIT SIGNAL */
2796 Session::update_region_name_map (boost::shared_ptr<Region> region)
2798 string::size_type last_period = region->name().find_last_of ('.');
2800 if (last_period != string::npos && last_period < region->name().length() - 1) {
2802 string base = region->name().substr (0, last_period);
2803 string number = region->name().substr (last_period+1);
2804 map<string,uint32_t>::iterator x;
2806 /* note that if there is no number, we get zero from atoi,
2810 region_name_map[base] = atoi (number);
2815 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2817 boost::shared_ptr<Region> region (weak_region.lock ());
2823 if (what_changed & Region::HiddenChanged) {
2824 /* relay hidden changes */
2825 RegionHiddenChange (region);
2828 if (what_changed & NameChanged) {
2829 update_region_name_map (region);
2834 Session::remove_region (boost::weak_ptr<Region> weak_region)
2836 RegionList::iterator i;
2837 boost::shared_ptr<Region> region (weak_region.lock ());
2843 bool removed = false;
2846 Glib::Mutex::Lock lm (region_lock);
2848 if ((i = regions.find (region->id())) != regions.end()) {
2854 /* mark dirty because something has changed even if we didn't
2855 remove the region from the region list.
2861 RegionRemoved(region); /* EMIT SIGNAL */
2865 boost::shared_ptr<Region>
2866 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2868 RegionList::iterator i;
2869 boost::shared_ptr<Region> region;
2871 Glib::Mutex::Lock lm (region_lock);
2873 for (i = regions.begin(); i != regions.end(); ++i) {
2877 if (region->whole_file()) {
2879 if (child->source_equivalent (region)) {
2885 return boost::shared_ptr<Region> ();
2889 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2891 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2892 (*i)->get_region_list_equivalent_regions (region, result);
2896 Session::destroy_region (boost::shared_ptr<Region> region)
2898 vector<boost::shared_ptr<Source> > srcs;
2901 if (region->playlist()) {
2902 region->playlist()->destroy_region (region);
2905 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2906 srcs.push_back (region->source (n));
2910 region->drop_references ();
2912 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2914 (*i)->mark_for_remove ();
2915 (*i)->drop_references ();
2917 cerr << "source was not used by any playlist\n";
2924 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2926 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2927 destroy_region (*i);
2933 Session::remove_last_capture ()
2935 list<boost::shared_ptr<Region> > r;
2937 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2939 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2940 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2943 r.insert (r.end(), l.begin(), l.end());
2948 destroy_regions (r);
2950 save_state (_current_snapshot_name);
2956 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2962 /* Source Management */
2965 Session::add_source (boost::shared_ptr<Source> source)
2967 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2968 pair<SourceMap::iterator,bool> result;
2970 entry.first = source->id();
2971 entry.second = source;
2974 Glib::Mutex::Lock lm (source_lock);
2975 result = sources.insert (entry);
2978 if (result.second) {
2979 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2983 boost::shared_ptr<AudioFileSource> afs;
2985 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2986 if (Config->get_auto_analyse_audio()) {
2987 Analyser::queue_source_for_analysis (source, false);
2993 Session::remove_source (boost::weak_ptr<Source> src)
2995 SourceMap::iterator i;
2996 boost::shared_ptr<Source> source = src.lock();
3003 Glib::Mutex::Lock lm (source_lock);
3005 if ((i = sources.find (source->id())) != sources.end()) {
3010 if (!_state_of_the_state & InCleanup) {
3012 /* save state so we don't end up with a session file
3013 referring to non-existent sources.
3016 save_state (_current_snapshot_name);
3020 /** Return the number of playlists (not regions) that contain @a src */
3022 Session::source_use_count (boost::shared_ptr<const Source> src) const
3025 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3026 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3027 r != (*p)->region_list().end(); ++r) {
3028 if ((*r)->uses_source(src)) {
3037 boost::shared_ptr<Source>
3038 Session::source_by_id (const PBD::ID& id)
3040 Glib::Mutex::Lock lm (source_lock);
3041 SourceMap::iterator i;
3042 boost::shared_ptr<Source> source;
3044 if ((i = sources.find (id)) != sources.end()) {
3051 boost::shared_ptr<Source>
3052 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3054 Glib::Mutex::Lock lm (source_lock);
3056 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3057 cerr << "comparing " << path << " with " << i->second->name() << endl;
3058 boost::shared_ptr<AudioFileSource> afs
3059 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3061 if (afs && afs->path() == path && chn == afs->channel()) {
3065 return boost::shared_ptr<Source>();
3070 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3073 string old_basename = PBD::basename_nosuffix (oldname);
3074 string new_legalized = legalize_for_path (newname);
3076 /* note: we know (or assume) the old path is already valid */
3080 /* destructive file sources have a name of the form:
3082 /path/to/Tnnnn-NAME(%[LR])?.wav
3084 the task here is to replace NAME with the new name.
3087 /* find last slash */
3091 string::size_type slash;
3092 string::size_type dash;
3094 if ((slash = path.find_last_of ('/')) == string::npos) {
3098 dir = path.substr (0, slash+1);
3100 /* '-' is not a legal character for the NAME part of the path */
3102 if ((dash = path.find_last_of ('-')) == string::npos) {
3106 prefix = path.substr (slash+1, dash-(slash+1));
3111 path += new_legalized;
3112 path += ".wav"; /* XXX gag me with a spoon */
3116 /* non-destructive file sources have a name of the form:
3118 /path/to/NAME-nnnnn(%[LR])?.ext
3120 the task here is to replace NAME with the new name.
3125 string::size_type slash;
3126 string::size_type dash;
3127 string::size_type postfix;
3129 /* find last slash */
3131 if ((slash = path.find_last_of ('/')) == string::npos) {
3135 dir = path.substr (0, slash+1);
3137 /* '-' is not a legal character for the NAME part of the path */
3139 if ((dash = path.find_last_of ('-')) == string::npos) {
3143 suffix = path.substr (dash+1);
3145 // Suffix is now everything after the dash. Now we need to eliminate
3146 // the nnnnn part, which is done by either finding a '%' or a '.'
3148 postfix = suffix.find_last_of ("%");
3149 if (postfix == string::npos) {
3150 postfix = suffix.find_last_of ('.');
3153 if (postfix != string::npos) {
3154 suffix = suffix.substr (postfix);
3156 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3160 const uint32_t limit = 10000;
3161 char buf[PATH_MAX+1];
3163 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3165 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3167 if (access (buf, F_OK) != 0) {
3175 error << "FATAL ERROR! Could not find a " << endl;
3183 /** Return the full path (in some session directory) for a new embedded source.
3184 * \a name must be a session-unique name that does not contain slashes
3185 * (e.g. as returned by new_*_source_name)
3188 Session::new_source_path_from_name (DataType type, const string& name)
3190 assert(name.find("/") == string::npos);
3192 SessionDirectory sdir(get_best_session_directory_for_new_source());
3195 if (type == DataType::AUDIO) {
3196 p = sdir.sound_path();
3197 } else if (type == DataType::MIDI) {
3198 p = sdir.midi_path();
3200 error << "Unknown source type, unable to create file path" << endmsg;
3205 return p.to_string();
3209 Session::peak_path (Glib::ustring base) const
3211 sys::path peakfile_path(_session_dir->peak_path());
3212 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3213 return peakfile_path.to_string();
3216 /** Return a unique name based on \a base for a new internal audio source */
3218 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3222 char buf[PATH_MAX+1];
3223 const uint32_t limit = 10000;
3227 legalized = legalize_for_path (base);
3229 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3230 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3232 vector<space_and_path>::iterator i;
3233 uint32_t existing = 0;
3235 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3237 SessionDirectory sdir((*i).path);
3239 spath = sdir.sound_path().to_string();
3244 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3245 spath.c_str(), cnt, legalized.c_str());
3246 } else if (nchan == 2) {
3248 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3249 spath.c_str(), cnt, legalized.c_str());
3251 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3252 spath.c_str(), cnt, legalized.c_str());
3254 } else if (nchan < 26) {
3255 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3256 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3258 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3259 spath.c_str(), cnt, legalized.c_str());
3268 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3269 } else if (nchan == 2) {
3271 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3273 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3275 } else if (nchan < 26) {
3276 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3278 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3282 if (sys::exists(buf)) {
3288 if (existing == 0) {
3293 error << string_compose(
3294 _("There are already %1 recordings for %2, which I consider too many."),
3295 limit, base) << endmsg;
3297 throw failed_constructor();
3301 return Glib::path_get_basename(buf);
3304 /** Create a new embedded audio source */
3305 boost::shared_ptr<AudioFileSource>
3306 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3308 const size_t n_chans = ds.n_channels().n_audio();
3309 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3310 const string path = new_source_path_from_name(DataType::AUDIO, name);
3311 return boost::dynamic_pointer_cast<AudioFileSource> (
3312 SourceFactory::createWritable (
3313 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3316 /** Return a unique name based on \a base for a new internal MIDI source */
3318 Session::new_midi_source_name (const string& base)
3321 char buf[PATH_MAX+1];
3322 const uint32_t limit = 10000;
3326 legalized = legalize_for_path (base);
3328 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3329 for (cnt = 1; cnt <= limit; ++cnt) {
3331 vector<space_and_path>::iterator i;
3332 uint32_t existing = 0;
3334 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3336 SessionDirectory sdir((*i).path);
3338 sys::path p = sdir.midi_path();
3341 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3343 if (sys::exists (buf)) {
3348 if (existing == 0) {
3353 error << string_compose(
3354 _("There are already %1 recordings for %2, which I consider too many."),
3355 limit, base) << endmsg;
3357 throw failed_constructor();
3361 return Glib::path_get_basename(buf);
3365 /** Create a new embedded MIDI source */
3366 boost::shared_ptr<MidiSource>
3367 Session::create_midi_source_for_session (MidiDiskstream& ds)
3369 const string name = new_midi_source_name (ds.name());
3370 const string path = new_source_path_from_name (DataType::MIDI, name);
3372 return boost::dynamic_pointer_cast<SMFSource> (
3373 SourceFactory::createWritable (
3374 DataType::MIDI, *this, path, true, false, frame_rate()));
3378 /* Playlist management */
3380 boost::shared_ptr<Playlist>
3381 Session::playlist_by_name (string name)
3383 Glib::Mutex::Lock lm (playlist_lock);
3384 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3385 if ((*i)->name() == name) {
3389 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3390 if ((*i)->name() == name) {
3395 return boost::shared_ptr<Playlist>();
3399 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3401 Glib::Mutex::Lock lm (playlist_lock);
3402 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3403 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3404 list.push_back (*i);
3407 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3408 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3409 list.push_back (*i);
3415 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3417 if (playlist->hidden()) {
3422 Glib::Mutex::Lock lm (playlist_lock);
3423 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3424 playlists.insert (playlists.begin(), playlist);
3425 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3426 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3431 playlist->release();
3436 PlaylistAdded (playlist); /* EMIT SIGNAL */
3440 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3443 Glib::Mutex::Lock lm (playlist_lock);
3444 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3447 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3454 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3456 boost::shared_ptr<Playlist> pl(wpl.lock());
3462 PlaylistList::iterator x;
3465 /* its not supposed to be visible */
3470 Glib::Mutex::Lock lm (playlist_lock);
3474 unused_playlists.insert (pl);
3476 if ((x = playlists.find (pl)) != playlists.end()) {
3477 playlists.erase (x);
3483 playlists.insert (pl);
3485 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3486 unused_playlists.erase (x);
3493 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3495 if (_state_of_the_state & Deletion) {
3499 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3506 Glib::Mutex::Lock lm (playlist_lock);
3508 PlaylistList::iterator i;
3510 i = find (playlists.begin(), playlists.end(), playlist);
3511 if (i != playlists.end()) {
3512 playlists.erase (i);
3515 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3516 if (i != unused_playlists.end()) {
3517 unused_playlists.erase (i);
3524 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3528 Session::set_audition (boost::shared_ptr<Region> r)
3530 pending_audition_region = r;
3531 add_post_transport_work (PostTransportAudition);
3532 _butler->schedule_transport_work ();
3536 Session::audition_playlist ()
3538 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3539 ev->region.reset ();
3544 Session::non_realtime_set_audition ()
3546 if (!pending_audition_region) {
3547 auditioner->audition_current_playlist ();
3549 auditioner->audition_region (pending_audition_region);
3550 pending_audition_region.reset ();
3552 AuditionActive (true); /* EMIT SIGNAL */
3556 Session::audition_region (boost::shared_ptr<Region> r)
3558 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3564 Session::cancel_audition ()
3566 if (auditioner->active()) {
3567 auditioner->cancel_audition ();
3568 AuditionActive (false); /* EMIT SIGNAL */
3573 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3575 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3579 Session::remove_empty_sounds ()
3581 vector<string> audio_filenames;
3583 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3585 Glib::Mutex::Lock lm (source_lock);
3587 TapeFileMatcher tape_file_matcher;
3589 remove_if (audio_filenames.begin(), audio_filenames.end(),
3590 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3592 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3594 sys::path audio_file_path (_session_dir->sound_path());
3596 audio_file_path /= *i;
3598 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3602 sys::remove (audio_file_path);
3603 const string peakfile = peak_path (audio_file_path.to_string());
3604 sys::remove (peakfile);
3606 catch (const sys::filesystem_error& err)
3608 error << err.what() << endmsg;
3615 Session::is_auditioning () const
3617 /* can be called before we have an auditioner object */
3619 return auditioner->active();
3626 Session::set_all_solo (bool yn)
3628 shared_ptr<RouteList> r = routes.reader ();
3630 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3631 if (!(*i)->is_hidden()) {
3632 (*i)->set_solo (yn, this);
3640 Session::set_all_listen (bool yn)
3642 shared_ptr<RouteList> r = routes.reader ();
3644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3645 if (!(*i)->is_hidden()) {
3646 (*i)->set_listen (yn, this);
3654 Session::set_all_mute (bool yn)
3656 shared_ptr<RouteList> r = routes.reader ();
3658 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3659 if (!(*i)->is_hidden()) {
3660 (*i)->set_mute (yn, this);
3668 Session::n_diskstreams () const
3672 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3674 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3675 if (!(*i)->hidden()) {
3683 Session::graph_reordered ()
3685 /* don't do this stuff if we are setting up connections
3686 from a set_state() call or creating new tracks.
3689 if (_state_of_the_state & InitialConnecting) {
3693 /* every track/bus asked for this to be handled but it was deferred because
3694 we were connecting. do it now.
3697 request_input_change_handling ();
3701 /* force all diskstreams to update their capture offset values to
3702 reflect any changes in latencies within the graph.
3705 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3707 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3708 (*i)->set_capture_offset ();
3713 Session::record_disenable_all ()
3715 record_enable_change_all (false);
3719 Session::record_enable_all ()
3721 record_enable_change_all (true);
3725 Session::record_enable_change_all (bool yn)
3727 shared_ptr<RouteList> r = routes.reader ();
3729 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3730 boost::shared_ptr<Track> t;
3732 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3733 t->set_record_enable (yn, this);
3737 /* since we don't keep rec-enable state, don't mark session dirty */
3741 Session::add_processor (Processor* processor)
3743 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3748 Session::remove_processor (Processor* processor)
3752 PortInsert* port_insert;
3754 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3755 insert_bitset[port_insert->bit_slot()] = false;
3756 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3757 send_bitset[send->bit_slot()] = false;
3758 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3759 return_bitset[send->bit_slot()] = false;
3766 Session::available_capture_duration ()
3768 float sample_bytes_on_disk = 4.0; // keep gcc happy
3770 switch (config.get_native_file_data_format()) {
3772 sample_bytes_on_disk = 4.0;
3776 sample_bytes_on_disk = 3.0;
3780 sample_bytes_on_disk = 2.0;
3784 /* impossible, but keep some gcc versions happy */
3785 fatal << string_compose (_("programming error: %1"),
3786 X_("illegal native file data format"))
3791 double scale = 4096.0 / sample_bytes_on_disk;
3793 if (_total_free_4k_blocks * scale > (double) max_frames) {
3797 return (nframes_t) floor (_total_free_4k_blocks * scale);
3801 Session::add_bundle (shared_ptr<Bundle> bundle)
3804 RCUWriter<BundleList> writer (_bundles);
3805 boost::shared_ptr<BundleList> b = writer.get_copy ();
3806 b->push_back (bundle);
3809 BundleAdded (bundle); /* EMIT SIGNAL */
3815 Session::remove_bundle (shared_ptr<Bundle> bundle)
3817 bool removed = false;
3820 RCUWriter<BundleList> writer (_bundles);
3821 boost::shared_ptr<BundleList> b = writer.get_copy ();
3822 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3824 if (i != b->end()) {
3831 BundleRemoved (bundle); /* EMIT SIGNAL */
3838 Session::bundle_by_name (string name) const
3840 boost::shared_ptr<BundleList> b = _bundles.reader ();
3842 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3843 if ((*i)->name() == name) {
3848 return boost::shared_ptr<Bundle> ();
3852 Session::tempo_map_changed (Change)
3856 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3857 (*i)->update_after_tempo_map_change ();
3860 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3861 (*i)->update_after_tempo_map_change ();
3867 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3868 * the given count with the current block size.
3871 Session::ensure_buffers (ChanCount howmany)
3873 if (current_block_size == 0) {
3874 return; // too early? (is this ok?)
3877 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3878 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3879 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3880 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3881 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3884 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3888 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3890 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3891 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3896 Session::next_insert_id ()
3898 /* this doesn't really loop forever. just think about it */
3901 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3902 if (!insert_bitset[n]) {
3903 insert_bitset[n] = true;
3909 /* none available, so resize and try again */
3911 insert_bitset.resize (insert_bitset.size() + 16, false);
3916 Session::next_send_id ()
3918 /* this doesn't really loop forever. just think about it */
3921 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3922 if (!send_bitset[n]) {
3923 send_bitset[n] = true;
3929 /* none available, so resize and try again */
3931 send_bitset.resize (send_bitset.size() + 16, false);
3936 Session::next_return_id ()
3938 /* this doesn't really loop forever. just think about it */
3941 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3942 if (!return_bitset[n]) {
3943 return_bitset[n] = true;
3949 /* none available, so resize and try again */
3951 return_bitset.resize (return_bitset.size() + 16, false);
3956 Session::mark_send_id (uint32_t id)
3958 if (id >= send_bitset.size()) {
3959 send_bitset.resize (id+16, false);
3961 if (send_bitset[id]) {
3962 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3964 send_bitset[id] = true;
3968 Session::mark_return_id (uint32_t id)
3970 if (id >= return_bitset.size()) {
3971 return_bitset.resize (id+16, false);
3973 if (return_bitset[id]) {
3974 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3976 return_bitset[id] = true;
3980 Session::mark_insert_id (uint32_t id)
3982 if (id >= insert_bitset.size()) {
3983 insert_bitset.resize (id+16, false);
3985 if (insert_bitset[id]) {
3986 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3988 insert_bitset[id] = true;
3991 /* Named Selection management */
3994 Session::named_selection_by_name (string name)
3996 Glib::Mutex::Lock lm (named_selection_lock);
3997 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3998 if ((*i)->name == name) {
4006 Session::add_named_selection (NamedSelection* named_selection)
4009 Glib::Mutex::Lock lm (named_selection_lock);
4010 named_selections.insert (named_selections.begin(), named_selection);
4013 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4019 NamedSelectionAdded (); /* EMIT SIGNAL */
4023 Session::remove_named_selection (NamedSelection* named_selection)
4025 bool removed = false;
4028 Glib::Mutex::Lock lm (named_selection_lock);
4030 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4032 if (i != named_selections.end()) {
4034 named_selections.erase (i);
4041 NamedSelectionRemoved (); /* EMIT SIGNAL */
4046 Session::reset_native_file_format ()
4048 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4050 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4051 (*i)->reset_write_sources (false);
4056 Session::route_name_unique (string n) const
4058 shared_ptr<RouteList> r = routes.reader ();
4060 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4061 if ((*i)->name() == n) {
4070 Session::route_name_internal (string n) const
4072 if (auditioner && auditioner->name() == n) {
4076 if (_click_io && _click_io->name() == n) {
4084 Session::n_playlists () const
4086 Glib::Mutex::Lock lm (playlist_lock);
4087 return playlists.size();
4091 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4093 if (!force && howmany <= _npan_buffers) {
4097 if (_pan_automation_buffer) {
4099 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4100 delete [] _pan_automation_buffer[i];
4103 delete [] _pan_automation_buffer;
4106 _pan_automation_buffer = new pan_t*[howmany];
4108 for (uint32_t i = 0; i < howmany; ++i) {
4109 _pan_automation_buffer[i] = new pan_t[nframes];
4112 _npan_buffers = howmany;
4116 Session::freeze (InterThreadInfo& itt)
4118 shared_ptr<RouteList> r = routes.reader ();
4120 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4122 boost::shared_ptr<Track> t;
4124 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4125 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4135 boost::shared_ptr<Region>
4136 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4137 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4138 InterThreadInfo& itt, bool enable_processing)
4140 boost::shared_ptr<Region> result;
4141 boost::shared_ptr<Playlist> playlist;
4142 boost::shared_ptr<AudioFileSource> fsource;
4144 char buf[PATH_MAX+1];
4145 ChanCount nchans(track.audio_diskstream()->n_channels());
4147 nframes_t this_chunk;
4150 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4151 const string sound_dir = sdir.sound_path().to_string();
4152 nframes_t len = end - start;
4155 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4156 end, start) << endmsg;
4160 // any bigger than this seems to cause stack overflows in called functions
4161 const nframes_t chunk_size = (128 * 1024)/4;
4163 // block all process callback handling
4165 block_processing ();
4167 /* call tree *MUST* hold route_lock */
4169 if ((playlist = track.diskstream()->playlist()) == 0) {
4173 /* external redirects will be a problem */
4175 if (track.has_external_redirects()) {
4179 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4181 for (x = 0; x < 99999; ++x) {
4182 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4183 if (access (buf, F_OK) != 0) {
4189 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4194 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4195 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4198 catch (failed_constructor& err) {
4199 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4203 srcs.push_back (fsource);
4206 /* XXX need to flush all redirects */
4211 /* create a set of reasonably-sized buffers */
4212 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4213 buffers.set_count(nchans);
4215 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4216 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4218 afs->prepare_for_peakfile_writes ();
4221 while (to_do && !itt.cancel) {
4223 this_chunk = min (to_do, chunk_size);
4225 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4230 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4231 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4234 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4240 start += this_chunk;
4241 to_do -= this_chunk;
4243 itt.progress = (float) (1.0 - ((double) to_do / len));
4252 xnow = localtime (&now);
4254 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4255 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4258 afs->update_header (position, *xnow, now);
4259 afs->flush_header ();
4263 /* construct a region to represent the bounced material */
4265 result = RegionFactory::create (srcs, 0,
4266 srcs.front()->length(srcs.front()->timeline_position()),
4267 region_name_from_path (srcs.front()->name(), true));
4272 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4273 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4276 afs->mark_for_remove ();
4279 (*src)->drop_references ();
4283 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4284 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4287 afs->done_with_peakfile_writes ();
4291 unblock_processing ();
4297 Session::get_silent_buffers (ChanCount count)
4299 assert(_silent_buffers->available() >= count);
4300 _silent_buffers->set_count(count);
4302 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4303 for (size_t i= 0; i < count.get(*t); ++i) {
4304 _silent_buffers->get(*t, i).clear();
4308 return *_silent_buffers;
4312 Session::get_scratch_buffers (ChanCount count)
4314 if (count != ChanCount::ZERO) {
4315 assert(_scratch_buffers->available() >= count);
4316 _scratch_buffers->set_count(count);
4318 _scratch_buffers->set_count (_scratch_buffers->available());
4321 return *_scratch_buffers;
4325 Session::get_mix_buffers (ChanCount count)
4327 assert(_mix_buffers->available() >= count);
4328 _mix_buffers->set_count(count);
4329 return *_mix_buffers;
4333 Session::ntracks () const
4336 shared_ptr<RouteList> r = routes.reader ();
4338 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4339 if (boost::dynamic_pointer_cast<Track> (*i)) {
4348 Session::nbusses () const
4351 shared_ptr<RouteList> r = routes.reader ();
4353 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4354 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4363 Session::add_automation_list(AutomationList *al)
4365 automation_lists[al->id()] = al;
4369 Session::compute_initial_length ()
4371 return _engine.frame_rate() * 60 * 5;
4375 Session::sync_order_keys (std::string const & base)
4377 if (!Config->get_sync_all_route_ordering()) {
4378 /* leave order keys as they are */
4382 boost::shared_ptr<RouteList> r = routes.reader ();
4384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4385 (*i)->sync_order_keys (base);
4388 Route::SyncOrderKeys (base); // EMIT SIGNAL
4392 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4394 Session::have_rec_enabled_diskstream () const
4396 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4399 /** Update the state of our rec-enabled diskstreams flag */
4401 Session::update_have_rec_enabled_diskstream ()
4403 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4404 DiskstreamList::iterator i = dsl->begin ();
4405 while (i != dsl->end () && (*i)->record_enabled () == false) {
4409 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4411 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4413 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4414 RecordStateChanged (); /* EMIT SIGNAL */
4419 Session::listen_position_changed ()
4423 switch (Config->get_listen_position()) {
4424 case AfterFaderListen:
4428 case PreFaderListen:
4433 boost::shared_ptr<RouteList> r = routes.reader ();
4435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4436 (*i)->put_control_outs_at (p);
4441 Session::solo_control_mode_changed ()
4443 /* cancel all solo or all listen when solo control mode changes */
4445 if (Config->get_solo_control_is_listen_control()) {
4446 set_all_solo (false);
4448 set_all_listen (false);
4453 Session::route_group_changed ()
4455 RouteGroupChanged (); /* EMIT SIGNAL */
4459 Session::get_available_sync_options () const
4461 vector<SyncSource> ret;
4463 ret.push_back (JACK);
4466 ret.push_back (MTC);
4469 if (midi_clock_port()) {
4470 ret.push_back (MIDIClock);