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.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.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>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/destructive_filesource.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/connection.h>
63 #include <ardour/slave.h>
64 #include <ardour/tempo.h>
65 #include <ardour/audio_track.h>
66 #include <ardour/midi_track.h>
67 #include <ardour/cycle_timer.h>
68 #include <ardour/named_selection.h>
69 #include <ardour/crossfade.h>
70 #include <ardour/playlist.h>
71 #include <ardour/click.h>
72 #include <ardour/data_type.h>
73 #include <ardour/buffer_set.h>
76 #include <ardour/osc.h>
82 using namespace ARDOUR;
84 using boost::shared_ptr;
86 const char* Session::_template_suffix = X_(".template");
87 const char* Session::_statefile_suffix = X_(".ardour");
88 const char* Session::_pending_suffix = X_(".pending");
89 const char* Session::sound_dir_name = X_("sounds");
90 const char* Session::tape_dir_name = X_("tapes");
91 const char* Session::peak_dir_name = X_("peaks");
92 const char* Session::dead_sound_dir_name = X_("dead_sounds");
94 Session::compute_peak_t Session::compute_peak = 0;
95 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
96 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
97 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
99 sigc::signal<int> Session::AskAboutPendingState;
100 sigc::signal<void> Session::SMPTEOffsetChanged;
101 sigc::signal<void> Session::SendFeedback;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _scratch_buffers(new BufferSet()),
261 _silent_buffers(new BufferSet()),
262 _send_buffers(new BufferSet()),
263 _mmc_port (default_mmc_port),
264 _mtc_port (default_mtc_port),
265 _midi_port (default_midi_port),
266 pending_events (2048),
267 //midi_requests (128), // the size of this should match the midi request pool size
268 _send_smpte_update (false),
269 diskstreams (new DiskstreamList),
270 routes (new RouteList),
271 auditioner ((Auditioner*) 0),
277 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
279 n_physical_outputs = _engine.n_physical_outputs();
280 n_physical_inputs = _engine.n_physical_inputs();
282 first_stage_init (fullpath, snapshot_name);
284 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
285 throw failed_constructor ();
288 if (second_stage_init (new_session)) {
289 throw failed_constructor ();
292 store_recent_sessions(_name, _path);
294 bool was_dirty = dirty();
296 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
299 DirtyChanged (); /* EMIT SIGNAL */
303 Session::Session (AudioEngine &eng,
305 string snapshot_name,
306 AutoConnectOption input_ac,
307 AutoConnectOption output_ac,
308 uint32_t control_out_channels,
309 uint32_t master_out_channels,
310 uint32_t requested_physical_in,
311 uint32_t requested_physical_out,
312 jack_nframes_t initial_length)
315 _scratch_buffers(new BufferSet()),
316 _silent_buffers(new BufferSet()),
317 _send_buffers(new BufferSet()),
318 _mmc_port (default_mmc_port),
319 _mtc_port (default_mtc_port),
320 _midi_port (default_midi_port),
321 pending_events (2048),
322 //midi_requests (16),
323 _send_smpte_update (false),
324 diskstreams (new DiskstreamList),
325 routes (new RouteList),
331 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
333 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
334 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
336 first_stage_init (fullpath, snapshot_name);
338 if (create (new_session, 0, initial_length)) {
339 throw failed_constructor ();
342 if (control_out_channels) {
343 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
350 if (master_out_channels) {
351 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
357 /* prohibit auto-connect to master, because there isn't one */
358 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
361 input_auto_connect = input_ac;
362 output_auto_connect = output_ac;
364 if (second_stage_init (new_session)) {
365 throw failed_constructor ();
368 store_recent_sessions(_name, _path);
370 bool was_dirty = dirty ();
372 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
375 DirtyChanged (); /* EMIT SIGNAL */
381 /* if we got to here, leaving pending capture state around
385 remove_pending_capture_state ();
387 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
388 _engine.remove_session ();
390 going_away (); /* EMIT SIGNAL */
392 terminate_butler_thread ();
393 //terminate_midi_thread ();
395 if (click_data && click_data != default_click) {
396 delete [] click_data;
399 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
400 delete [] click_emphasis_data;
405 delete _scratch_buffers;
406 delete _silent_buffers;
407 delete _send_buffers;
409 AudioDiskstream::free_working_buffers();
411 #undef TRACK_DESTRUCTION
412 #ifdef TRACK_DESTRUCTION
413 cerr << "delete named selections\n";
414 #endif /* TRACK_DESTRUCTION */
415 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
416 NamedSelectionList::iterator tmp;
425 #ifdef TRACK_DESTRUCTION
426 cerr << "delete playlists\n";
427 #endif /* TRACK_DESTRUCTION */
428 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
429 PlaylistList::iterator tmp;
439 #ifdef TRACK_DESTRUCTION
440 cerr << "delete regions\n";
441 #endif /* TRACK_DESTRUCTION */
442 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
443 RegionList::iterator tmp;
453 #ifdef TRACK_DESTRUCTION
454 cerr << "delete routes\n";
455 #endif /* TRACK_DESTRUCTION */
457 RCUWriter<RouteList> writer (routes);
458 boost::shared_ptr<RouteList> r = writer.get_copy ();
459 for (RouteList::iterator i = r->begin(); i != r->end(); ) {
460 RouteList::iterator tmp;
463 (*i)->drop_references ();
467 /* writer goes out of scope and updates master */
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete diskstreams\n";
474 #endif /* TRACK_DESTRUCTION */
476 RCUWriter<DiskstreamList> dwriter (diskstreams);
477 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
478 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
479 DiskstreamList::iterator tmp;
484 (*i)->drop_references ();
490 diskstreams.flush ();
492 #ifdef TRACK_DESTRUCTION
493 cerr << "delete audio sources\n";
494 #endif /* TRACK_DESTRUCTION */
495 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
496 SourceList::iterator tmp;
506 #ifdef TRACK_DESTRUCTION
507 cerr << "delete mix groups\n";
508 #endif /* TRACK_DESTRUCTION */
509 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
510 list<RouteGroup*>::iterator tmp;
520 #ifdef TRACK_DESTRUCTION
521 cerr << "delete edit groups\n";
522 #endif /* TRACK_DESTRUCTION */
523 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
524 list<RouteGroup*>::iterator tmp;
534 #ifdef TRACK_DESTRUCTION
535 cerr << "delete connections\n";
536 #endif /* TRACK_DESTRUCTION */
537 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
538 ConnectionList::iterator tmp;
548 if (butler_mixdown_buffer) {
549 delete [] butler_mixdown_buffer;
552 if (butler_gain_buffer) {
553 delete [] butler_gain_buffer;
556 Crossfade::set_buffer_size (0);
568 Session::set_worst_io_latencies ()
570 _worst_output_latency = 0;
571 _worst_input_latency = 0;
573 if (!_engine.connected()) {
577 boost::shared_ptr<RouteList> r = routes.reader ();
579 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
580 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
581 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
586 Session::when_engine_running ()
588 string first_physical_output;
590 /* we don't want to run execute this again */
592 first_time_running.disconnect ();
594 set_block_size (_engine.frames_per_cycle());
595 set_frame_rate (_engine.frame_rate());
597 /* every time we reconnect, recompute worst case output latencies */
599 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
601 if (synced_to_jack()) {
602 _engine.transport_stop ();
605 if (Config->get_jack_time_master()) {
606 _engine.transport_locate (_transport_frame);
614 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
616 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
618 /* existing state for Click */
620 if (_click_io->set_state (*child->children().front()) == 0) {
622 _clicking = click_requested;
626 error << _("could not setup Click I/O") << endmsg;
632 /* default state for Click */
634 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
636 if (first_physical_output.length()) {
637 if (_click_io->add_output_port (first_physical_output, this)) {
638 // relax, even though its an error
640 _clicking = click_requested;
646 catch (failed_constructor& err) {
647 error << _("cannot setup Click I/O") << endmsg;
650 set_worst_io_latencies ();
653 ControlChanged (Clicking); /* EMIT SIGNAL */
656 if (auditioner == 0) {
658 /* we delay creating the auditioner till now because
659 it makes its own connections to ports named
660 in the ARDOUR_RC config file. the engine has
661 to be running for this to work.
665 auditioner.reset (new Auditioner (*this));
668 catch (failed_constructor& err) {
669 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
673 /* Create a set of Connection objects that map
674 to the physical outputs currently available
679 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
681 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
683 Connection* c = new OutputConnection (buf, true);
686 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
691 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
693 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
695 Connection* c = new InputConnection (buf, true);
698 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
705 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
707 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
709 Connection* c = new OutputConnection (buf, true);
713 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
714 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
719 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
721 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
723 Connection* c = new InputConnection (buf, true);
727 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
728 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
737 /* create master/control ports */
742 /* force the master to ignore any later call to this */
744 if (_master_out->pending_state_node) {
745 _master_out->ports_became_legal();
748 /* no panner resets till we are through */
750 _master_out->defer_pan_reset ();
752 while (_master_out->n_inputs().get(DataType::AUDIO)
753 < _master_out->input_maximum().get(DataType::AUDIO)) {
754 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
755 error << _("cannot setup master inputs")
761 while (_master_out->n_outputs().get(DataType::AUDIO)
762 < _master_out->output_maximum().get(DataType::AUDIO)) {
763 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
764 error << _("cannot setup master outputs")
771 _master_out->allow_pan_reset ();
775 Connection* c = new OutputConnection (_("Master Out"), true);
777 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
779 c->add_connection ((int) n, _master_out->input(n)->name());
786 /* catch up on send+insert cnts */
790 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
793 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
794 if (id > insert_cnt) {
802 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
805 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
812 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
814 /* hook us up to the engine */
816 _engine.set_session (this);
821 osc->set_session (*this);
824 _state_of_the_state = Clean;
826 DirtyChanged (); /* EMIT SIGNAL */
830 Session::hookup_io ()
832 /* stop graph reordering notifications from
833 causing resorts, etc.
836 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
838 /* Tell all IO objects to create their ports */
845 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
846 if (_control_out->add_input_port ("", this)) {
847 error << _("cannot setup control inputs")
853 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
854 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
855 error << _("cannot set up master outputs")
863 /* Tell all IO objects to connect themselves together */
865 IO::enable_connecting ();
867 /* Now reset all panners */
869 IO::reset_panners ();
871 /* Anyone who cares about input state, wake up and do something */
873 IOConnectionsComplete (); /* EMIT SIGNAL */
875 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
877 /* now handle the whole enchilada as if it was one
883 /* update mixer solo state */
889 Session::playlist_length_changed (Playlist* pl)
891 /* we can't just increase end_location->end() if pl->get_maximum_extent()
892 if larger. if the playlist used to be the longest playlist,
893 and its now shorter, we have to decrease end_location->end(). hence,
894 we have to iterate over all diskstreams and check the
895 playlists currently in use.
901 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
905 if ((playlist = dstream->playlist()) != 0) {
906 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
909 /* see comment in playlist_length_changed () */
914 Session::record_enabling_legal () const
916 /* this used to be in here, but survey says.... we don't need to restrict it */
917 // if (record_status() == Recording) {
928 Session::set_auto_play (bool yn)
930 if (auto_play != yn) {
933 ControlChanged (AutoPlay);
938 Session::set_auto_return (bool yn)
940 if (auto_return != yn) {
943 ControlChanged (AutoReturn);
948 Session::set_crossfades_active (bool yn)
950 if (crossfades_active != yn) {
951 crossfades_active = yn;
953 ControlChanged (CrossFadesActive);
958 Session::set_do_not_record_plugins (bool yn)
960 if (do_not_record_plugins != yn) {
961 do_not_record_plugins = yn;
963 ControlChanged (RecordingPlugins);
968 Session::set_auto_input (bool yn)
970 if (auto_input != yn) {
973 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
974 /* auto-input only makes a difference if we're rolling */
976 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
978 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
979 if ((*i)->record_enabled ()) {
980 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
981 (*i)->monitor_input (!auto_input);
987 ControlChanged (AutoInput);
992 Session::reset_input_monitor_state ()
994 if (transport_rolling()) {
996 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
998 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
999 if ((*i)->record_enabled ()) {
1000 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1001 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
1005 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1007 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1008 if ((*i)->record_enabled ()) {
1009 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1010 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1018 Session::set_input_auto_connect (bool yn)
1021 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1023 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1029 Session::get_input_auto_connect () const
1031 return (input_auto_connect & AutoConnectPhysical);
1035 Session::set_output_auto_connect (AutoConnectOption aco)
1037 output_auto_connect = aco;
1042 Session::auto_punch_start_changed (Location* location)
1044 replace_event (Event::PunchIn, location->start());
1046 if (get_record_enabled() && get_punch_in()) {
1047 /* capture start has been changed, so save new pending state */
1048 save_state ("", true);
1053 Session::auto_punch_end_changed (Location* location)
1055 jack_nframes_t when_to_stop = location->end();
1056 // when_to_stop += _worst_output_latency + _worst_input_latency;
1057 replace_event (Event::PunchOut, when_to_stop);
1061 Session::auto_punch_changed (Location* location)
1063 jack_nframes_t when_to_stop = location->end();
1065 replace_event (Event::PunchIn, location->start());
1066 //when_to_stop += _worst_output_latency + _worst_input_latency;
1067 replace_event (Event::PunchOut, when_to_stop);
1071 Session::auto_loop_changed (Location* location)
1073 replace_event (Event::AutoLoop, location->end(), location->start());
1075 if (transport_rolling() && get_auto_loop()) {
1077 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1079 if (_transport_frame > location->end()) {
1080 // relocate to beginning of loop
1081 clear_events (Event::LocateRoll);
1083 request_locate (location->start(), true);
1086 else if (seamless_loop && !loop_changing) {
1088 // schedule a locate-roll to refill the diskstreams at the
1089 // previous loop end
1090 loop_changing = true;
1092 if (location->end() > last_loopend) {
1093 clear_events (Event::LocateRoll);
1094 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1101 last_loopend = location->end();
1106 Session::set_auto_punch_location (Location* location)
1110 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1111 auto_punch_start_changed_connection.disconnect();
1112 auto_punch_end_changed_connection.disconnect();
1113 auto_punch_changed_connection.disconnect();
1114 existing->set_auto_punch (false, this);
1115 remove_event (existing->start(), Event::PunchIn);
1116 clear_events (Event::PunchOut);
1117 auto_punch_location_changed (0);
1122 if (location == 0) {
1126 if (location->end() <= location->start()) {
1127 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1131 auto_punch_start_changed_connection.disconnect();
1132 auto_punch_end_changed_connection.disconnect();
1133 auto_punch_changed_connection.disconnect();
1135 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1136 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1137 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1139 location->set_auto_punch (true, this);
1140 auto_punch_location_changed (location);
1144 Session::set_punch_in (bool yn)
1146 if (punch_in == yn) {
1152 if ((location = _locations.auto_punch_location()) != 0) {
1153 if ((punch_in = yn) == true) {
1154 replace_event (Event::PunchIn, location->start());
1156 remove_event (location->start(), Event::PunchIn);
1161 ControlChanged (PunchIn); /* EMIT SIGNAL */
1165 Session::set_punch_out (bool yn)
1167 if (punch_out == yn) {
1173 if ((location = _locations.auto_punch_location()) != 0) {
1174 if ((punch_out = yn) == true) {
1175 replace_event (Event::PunchOut, location->end());
1177 clear_events (Event::PunchOut);
1182 ControlChanged (PunchOut); /* EMIT SIGNAL */
1186 Session::set_auto_loop_location (Location* location)
1190 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1191 auto_loop_start_changed_connection.disconnect();
1192 auto_loop_end_changed_connection.disconnect();
1193 auto_loop_changed_connection.disconnect();
1194 existing->set_auto_loop (false, this);
1195 remove_event (existing->end(), Event::AutoLoop);
1196 auto_loop_location_changed (0);
1201 if (location == 0) {
1205 if (location->end() <= location->start()) {
1206 error << _("Session: you can't use a mark for auto loop") << endmsg;
1210 last_loopend = location->end();
1212 auto_loop_start_changed_connection.disconnect();
1213 auto_loop_end_changed_connection.disconnect();
1214 auto_loop_changed_connection.disconnect();
1216 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1217 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1218 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1220 location->set_auto_loop (true, this);
1221 auto_loop_location_changed (location);
1225 Session::locations_added (Location* ignored)
1231 Session::locations_changed ()
1233 _locations.apply (*this, &Session::handle_locations_changed);
1237 Session::handle_locations_changed (Locations::LocationList& locations)
1239 Locations::LocationList::iterator i;
1241 bool set_loop = false;
1242 bool set_punch = false;
1244 for (i = locations.begin(); i != locations.end(); ++i) {
1248 if (location->is_auto_punch()) {
1249 set_auto_punch_location (location);
1252 if (location->is_auto_loop()) {
1253 set_auto_loop_location (location);
1260 set_auto_loop_location (0);
1263 set_auto_punch_location (0);
1270 Session::enable_record ()
1272 /* XXX really atomic compare+swap here */
1273 if (g_atomic_int_get (&_record_status) != Recording) {
1274 g_atomic_int_set (&_record_status, Recording);
1275 _last_record_location = _transport_frame;
1276 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1278 if (Config->get_use_hardware_monitoring() && auto_input) {
1279 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1280 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1281 if ((*i)->record_enabled ()) {
1282 (*i)->monitor_input (true);
1287 RecordStateChanged ();
1292 Session::disable_record (bool rt_context, bool force)
1296 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1298 if (!Config->get_latched_record_enable () || force) {
1299 g_atomic_int_set (&_record_status, Disabled);
1301 if (rs == Recording) {
1302 g_atomic_int_set (&_record_status, Enabled);
1306 // FIXME: timestamp correct? [DR]
1307 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1308 // does this /need/ to be sent in all cases?
1310 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1312 if (Config->get_use_hardware_monitoring() && auto_input) {
1313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1315 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1316 if ((*i)->record_enabled ()) {
1317 (*i)->monitor_input (false);
1322 RecordStateChanged (); /* emit signal */
1325 remove_pending_capture_state ();
1331 Session::step_back_from_record ()
1333 g_atomic_int_set (&_record_status, Enabled);
1335 if (Config->get_use_hardware_monitoring()) {
1336 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1338 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1339 if (auto_input && (*i)->record_enabled ()) {
1340 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1341 (*i)->monitor_input (false);
1348 Session::maybe_enable_record ()
1350 g_atomic_int_set (&_record_status, Enabled);
1352 /* XXX this save should really happen in another thread. its needed so that
1353 pending capture state can be recovered if we crash.
1356 save_state ("", true);
1358 if (_transport_speed) {
1363 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1364 RecordStateChanged (); /* EMIT SIGNAL */
1371 Session::audible_frame () const
1374 jack_nframes_t offset;
1377 /* the first of these two possible settings for "offset"
1378 mean that the audible frame is stationary until
1379 audio emerges from the latency compensation
1382 the second means that the audible frame is stationary
1383 until audio would emerge from a physical port
1384 in the absence of any plugin latency compensation
1387 offset = _worst_output_latency;
1389 if (offset > current_block_size) {
1390 offset -= current_block_size;
1392 /* XXX is this correct? if we have no external
1393 physical connections and everything is internal
1394 then surely this is zero? still, how
1395 likely is that anyway?
1397 offset = current_block_size;
1400 if (synced_to_jack()) {
1401 tf = _engine.transport_frame();
1403 tf = _transport_frame;
1406 if (_transport_speed == 0) {
1416 if (!non_realtime_work_pending()) {
1420 /* take latency into account */
1429 Session::set_frame_rate (jack_nframes_t frames_per_second)
1431 /** \fn void Session::set_frame_size(jack_nframes_t)
1432 the AudioEngine object that calls this guarantees
1433 that it will not be called while we are also in
1434 ::process(). Its fine to do things that block
1438 _current_frame_rate = frames_per_second;
1439 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1441 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1443 // XXX we need some equivalent to this, somehow
1444 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1448 /* XXX need to reset/reinstantiate all LADSPA plugins */
1452 Session::set_block_size (jack_nframes_t nframes)
1454 /* the AudioEngine guarantees
1455 that it will not be called while we are also in
1456 ::process(). It is therefore fine to do things that block
1462 current_block_size = nframes;
1464 ensure_buffers(_scratch_buffers->available());
1466 if (_gain_automation_buffer) {
1467 delete [] _gain_automation_buffer;
1469 _gain_automation_buffer = new gain_t[nframes];
1471 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1473 boost::shared_ptr<RouteList> r = routes.reader ();
1475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1476 (*i)->set_block_size (nframes);
1479 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1480 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1481 (*i)->set_block_size (nframes);
1484 set_worst_io_latencies ();
1489 Session::set_default_fade (float steepness, float fade_msecs)
1492 jack_nframes_t fade_frames;
1494 /* Don't allow fade of less 1 frame */
1496 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1503 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1507 default_fade_msecs = fade_msecs;
1508 default_fade_steepness = steepness;
1511 // jlc, WTF is this!
1512 Glib::RWLock::ReaderLock lm (route_lock);
1513 AudioRegion::set_default_fade (steepness, fade_frames);
1518 /* XXX have to do this at some point */
1519 /* foreach region using default fade, reset, then
1520 refill_all_diskstream_buffers ();
1525 struct RouteSorter {
1526 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1527 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1529 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1532 if (r1->fed_by.empty()) {
1533 if (r2->fed_by.empty()) {
1534 /* no ardour-based connections inbound to either route. just use signal order */
1535 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1537 /* r2 has connections, r1 does not; run r1 early */
1541 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1548 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1550 shared_ptr<Route> r2;
1552 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1553 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1557 /* make a copy of the existing list of routes that feed r1 */
1559 set<shared_ptr<Route> > existing = r1->fed_by;
1561 /* for each route that feeds r1, recurse, marking it as feeding
1565 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1568 /* r2 is a route that feeds r1 which somehow feeds base. mark
1569 base as being fed by r2
1572 rbase->fed_by.insert (r2);
1576 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1580 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1584 /* now recurse, so that we can mark base as being fed by
1585 all routes that feed r2
1588 trace_terminal (r2, rbase);
1595 Session::resort_routes ()
1597 /* don't do anything here with signals emitted
1598 by Routes while we are being destroyed.
1601 if (_state_of_the_state & Deletion) {
1608 RCUWriter<RouteList> writer (routes);
1609 shared_ptr<RouteList> r = writer.get_copy ();
1610 resort_routes_using (r);
1611 /* writer goes out of scope and forces update */
1616 Session::resort_routes_using (shared_ptr<RouteList> r)
1618 RouteList::iterator i, j;
1620 for (i = r->begin(); i != r->end(); ++i) {
1622 (*i)->fed_by.clear ();
1624 for (j = r->begin(); j != r->end(); ++j) {
1626 /* although routes can feed themselves, it will
1627 cause an endless recursive descent if we
1628 detect it. so don't bother checking for
1636 if ((*j)->feeds (*i)) {
1637 (*i)->fed_by.insert (*j);
1642 for (i = r->begin(); i != r->end(); ++i) {
1643 trace_terminal (*i, *i);
1650 cerr << "finished route resort\n";
1652 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1653 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1660 list<boost::shared_ptr<MidiTrack> >
1661 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1663 char track_name[32];
1664 uint32_t track_id = 0;
1666 uint32_t channels_used = 0;
1668 RouteList new_routes;
1669 list<boost::shared_ptr<MidiTrack> > ret;
1671 /* count existing audio tracks */
1674 shared_ptr<RouteList> r = routes.reader ();
1676 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1677 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1678 if (!(*i)->hidden()) {
1680 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1688 /* check for duplicate route names, since we might have pre-existing
1689 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1690 save, close,restart,add new route - first named route is now
1698 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1700 if (route_by_name (track_name) == 0) {
1704 } while (track_id < (UINT_MAX-1));
1707 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1709 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1710 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1713 channels_used += track->n_inputs ().get(DataType::MIDI);
1715 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1716 track->set_remote_control_id (ntracks());
1718 new_routes.push_back (track);
1719 ret.push_back (track);
1722 catch (failed_constructor &err) {
1723 error << _("Session: could not create new midi track.") << endmsg;
1724 // XXX should we delete the tracks already created?
1732 if (!new_routes.empty()) {
1733 add_routes (new_routes, false);
1734 save_state (_current_snapshot_name);
1741 std::list<boost::shared_ptr<MidiTrack> >
1742 Session::new_midi_track (TrackMode mode)
1744 char track_name[32];
1746 uint32_t channels_used = 0;
1749 /* count existing midi tracks */
1752 shared_ptr<RouteList> r = routes.reader ();
1754 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1755 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1756 if (!(*i)->hidden()) {
1758 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1764 /* check for duplicate route names, since we might have pre-existing
1765 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1766 save, close,restart,add new route - first named route is now
1771 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, n+1);
1772 if (route_by_name (track_name) == 0) {
1777 } while (n < (UINT_MAX-1));
1780 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1782 if (track->ensure_io (1, 1, false, this)) {
1783 error << string_compose (_("cannot configure %1 in/%2 out configuration for new midi track"), track_name)
1787 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1791 track->set_remote_control_id (ntracks());
1795 catch (failed_constructor &err) {
1796 error << _("Session: could not create new midi track.") << endmsg;
1797 return shared_ptr<MidiTrack> ((MidiTrack*) 0);
1801 boost::shared_ptr<Route>
1802 Session::new_midi_route ()
1808 /* count existing midi busses */
1810 shared_ptr<RouteList> r = routes.reader ();
1812 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1813 if (dynamic_cast<MidiTrack*>((*i).get()) == 0) {
1814 if (!(*i)->hidden()) {
1822 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1823 if (route_by_name (bus_name) == 0) {
1828 } while (n < (UINT_MAX-1));
1831 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::MIDI));
1833 if (bus->ensure_io (1, 1, false, this)) {
1834 error << (_("cannot configure 1 in/1 out configuration for new midi track"))
1838 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1842 if (input_auto_connect & AutoConnectPhysical) {
1843 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1846 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1851 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1855 if (output_auto_connect & AutoConnectPhysical) {
1856 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1857 } else if (output_auto_connect & AutoConnectMaster) {
1859 port = _master_out->input (x%_master_out->n_inputs())->name();
1863 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1870 vector<string> cports;
1871 uint32_t ni = _control_out->n_inputs();
1873 for (uint32_t n = 0; n < ni; ++n) {
1874 cports.push_back (_control_out->input(n)->name());
1876 bus->set_control_outs (cports);
1883 catch (failed_constructor &err) {
1884 error << _("Session: could not create new MIDI route.") << endmsg;
1885 return shared_ptr<Route> ((Route*) 0);
1890 list<boost::shared_ptr<AudioTrack> >
1891 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1893 char track_name[32];
1894 uint32_t track_id = 0;
1896 uint32_t channels_used = 0;
1898 RouteList new_routes;
1899 list<boost::shared_ptr<AudioTrack> > ret;
1901 /* count existing audio tracks */
1904 shared_ptr<RouteList> r = routes.reader ();
1906 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1907 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1908 if (!(*i)->hidden()) {
1910 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1916 vector<string> physinputs;
1917 vector<string> physoutputs;
1918 uint32_t nphysical_in;
1919 uint32_t nphysical_out;
1921 _engine.get_physical_outputs (physoutputs);
1922 _engine.get_physical_inputs (physinputs);
1926 /* check for duplicate route names, since we might have pre-existing
1927 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1928 save, close,restart,add new route - first named route is now
1936 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1938 if (route_by_name (track_name) == 0) {
1942 } while (track_id < (UINT_MAX-1));
1944 if (input_auto_connect & AutoConnectPhysical) {
1945 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1950 if (output_auto_connect & AutoConnectPhysical) {
1951 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1957 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1959 if (track->ensure_io (input_channels, output_channels, false, this)) {
1960 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1961 input_channels, output_channels)
1966 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1970 if (input_auto_connect & AutoConnectPhysical) {
1971 port = physinputs[(channels_used+x)%nphysical_in];
1974 if (port.length() && track->connect_input (track->input (x), port, this)) {
1980 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1984 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1985 port = physoutputs[(channels_used+x)%nphysical_out];
1986 } else if (output_auto_connect & AutoConnectMaster) {
1988 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1992 if (port.length() && track->connect_output (track->output (x), port, this)) {
1997 channels_used += track->n_inputs ().get(DataType::AUDIO);
2000 vector<string> cports;
2001 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
2003 for (n = 0; n < ni; ++n) {
2004 cports.push_back (_control_out->input(n)->name());
2007 track->set_control_outs (cports);
2010 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
2011 track->set_remote_control_id (ntracks());
2013 new_routes.push_back (track);
2014 ret.push_back (track);
2017 catch (failed_constructor &err) {
2018 error << _("Session: could not create new audio track.") << endmsg;
2019 // XXX should we delete the tracks already created?
2027 if (!new_routes.empty()) {
2028 add_routes (new_routes, false);
2029 save_state (_current_snapshot_name);
2036 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
2039 uint32_t bus_id = 1;
2044 /* count existing audio busses */
2047 shared_ptr<RouteList> r = routes.reader ();
2049 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2050 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2051 if (!(*i)->hidden()) {
2058 vector<string> physinputs;
2059 vector<string> physoutputs;
2061 _engine.get_physical_outputs (physoutputs);
2062 _engine.get_physical_inputs (physinputs);
2069 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
2071 if (route_by_name (bus_name) == 0) {
2075 } while (bus_id < (UINT_MAX-1));
2078 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
2080 if (bus->ensure_io (input_channels, output_channels, false, this)) {
2081 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2082 input_channels, output_channels)
2086 for (uint32_t x = 0; x < bus->n_inputs().get(DataType::AUDIO); ++x) {
2090 if (input_auto_connect & AutoConnectPhysical) {
2091 port = physinputs[((n+x)%n_physical_inputs)];
2094 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
2099 for (uint32_t x = 0; x < bus->n_outputs().get(DataType::AUDIO); ++x) {
2103 if (output_auto_connect & AutoConnectPhysical) {
2104 port = physoutputs[((n+x)%n_physical_outputs)];
2105 } else if (output_auto_connect & AutoConnectMaster) {
2107 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
2111 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2117 vector<string> cports;
2118 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
2120 for (uint32_t n = 0; n < ni; ++n) {
2121 cports.push_back (_control_out->input(n)->name());
2123 bus->set_control_outs (cports);
2126 ret.push_back (bus);
2130 catch (failed_constructor &err) {
2131 error << _("Session: could not create new audio route.") << endmsg;
2140 add_routes (ret, false);
2141 save_state (_current_snapshot_name);
2149 Session::add_routes (RouteList& new_routes, bool save)
2152 RCUWriter<RouteList> writer (routes);
2153 shared_ptr<RouteList> r = writer.get_copy ();
2154 r->insert (r->end(), new_routes.begin(), new_routes.end());
2155 resort_routes_using (r);
2158 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2159 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
2160 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2161 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2162 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2164 if ((*x)->master()) {
2168 if ((*x)->control()) {
2169 _control_out = (*x);
2176 save_state (_current_snapshot_name);
2179 RouteAdded (new_routes); /* EMIT SIGNAL */
2183 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2185 /* need to do this in case we're rolling at the time, to prevent false underruns */
2186 dstream->do_refill_with_alloc();
2189 RCUWriter<DiskstreamList> writer (diskstreams);
2190 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2191 ds->push_back (dstream);
2194 dstream->set_block_size (current_block_size);
2196 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2197 /* this will connect to future changes, and check the current length */
2198 diskstream_playlist_changed (dstream);
2200 dstream->prepare ();
2204 Session::remove_route (shared_ptr<Route> route)
2207 RCUWriter<RouteList> writer (routes);
2208 shared_ptr<RouteList> rs = writer.get_copy ();
2211 /* deleting the master out seems like a dumb
2212 idea, but its more of a UI policy issue
2216 if (route == _master_out) {
2217 _master_out = shared_ptr<Route> ((Route*) 0);
2220 if (route == _control_out) {
2221 _control_out = shared_ptr<Route> ((Route*) 0);
2223 /* cancel control outs for all routes */
2225 vector<string> empty;
2227 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2228 (*r)->set_control_outs (empty);
2232 update_route_solo_state ();
2234 /* writer goes out of scope, forces route list update */
2238 boost::shared_ptr<Diskstream> ds;
2240 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2241 ds = t->diskstream();
2247 RCUWriter<DiskstreamList> dsl (diskstreams);
2248 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2253 find_current_end ();
2255 update_latency_compensation (false, false);
2258 /* XXX should we disconnect from the Route's signals ? */
2260 save_state (_current_snapshot_name);
2262 /* try to cause everyone to drop their references */
2264 route->drop_references ();
2268 Session::route_mute_changed (void* src)
2274 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2276 if (solo_update_disabled) {
2283 is_track = (dynamic_cast<Track*>(route.get()) != 0);
2285 shared_ptr<RouteList> r = routes.reader ();
2287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2293 /* don't mess with busses */
2295 if (dynamic_cast<Track*>((*i).get()) == 0) {
2301 /* don't mess with tracks */
2303 if (dynamic_cast<Track*>((*i).get()) != 0) {
2308 if ((*i) != route &&
2309 ((*i)->mix_group () == 0 ||
2310 (*i)->mix_group () != route->mix_group () ||
2311 !route->mix_group ()->is_active())) {
2313 if ((*i)->soloed()) {
2315 /* if its already soloed, and solo latching is enabled,
2316 then leave it as it is.
2319 if (_solo_latched) {
2326 solo_update_disabled = true;
2327 (*i)->set_solo (false, src);
2328 solo_update_disabled = false;
2332 bool something_soloed = false;
2333 bool same_thing_soloed = false;
2334 bool signal = false;
2336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 if ((*i)->soloed()) {
2338 something_soloed = true;
2339 if (dynamic_cast<Track*>((*i).get())) {
2341 same_thing_soloed = true;
2346 same_thing_soloed = true;
2354 if (something_soloed != currently_soloing) {
2356 currently_soloing = something_soloed;
2359 modify_solo_mute (is_track, same_thing_soloed);
2362 SoloActive (currently_soloing);
2369 Session::set_solo_latched (bool yn)
2371 if (yn != _solo_latched) {
2374 ControlChanged (SoloLatch);
2379 Session::update_route_solo_state ()
2382 bool is_track = false;
2383 bool signal = false;
2385 /* caller must hold RouteLock */
2387 /* this is where we actually implement solo by changing
2388 the solo mute setting of each track.
2391 shared_ptr<RouteList> r = routes.reader ();
2393 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2394 if ((*i)->soloed()) {
2396 if (dynamic_cast<Track*>((*i).get())) {
2403 if (mute != currently_soloing) {
2405 currently_soloing = mute;
2408 if (!is_track && !mute) {
2410 /* nothing is soloed */
2412 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2413 (*i)->set_solo_mute (false);
2423 modify_solo_mute (is_track, mute);
2426 SoloActive (currently_soloing);
2431 Session::modify_solo_mute (bool is_track, bool mute)
2433 shared_ptr<RouteList> r = routes.reader ();
2435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2439 /* only alter track solo mute */
2441 if (dynamic_cast<Track*>((*i).get())) {
2442 if ((*i)->soloed()) {
2443 (*i)->set_solo_mute (!mute);
2445 (*i)->set_solo_mute (mute);
2451 /* only alter bus solo mute */
2453 if (!dynamic_cast<Track*>((*i).get())) {
2455 if ((*i)->soloed()) {
2457 (*i)->set_solo_mute (false);
2461 /* don't mute master or control outs
2462 in response to another bus solo
2465 if ((*i) != _master_out &&
2466 (*i) != _control_out) {
2467 (*i)->set_solo_mute (mute);
2478 Session::catch_up_on_solo ()
2480 /* this is called after set_state() to catch the full solo
2481 state, which can't be correctly determined on a per-route
2482 basis, but needs the global overview that only the session
2485 update_route_solo_state();
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 jack_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
2549 jack_nframes_t max = 0;
2552 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2554 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2555 Playlist* pl = (*i)->playlist();
2556 if ((me = pl->get_maximum_extent()) > max) {
2564 boost::shared_ptr<Diskstream>
2565 Session::diskstream_by_name (string name)
2567 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2569 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2570 if ((*i)->name() == name) {
2575 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2578 boost::shared_ptr<Diskstream>
2579 Session::diskstream_by_id (const PBD::ID& id)
2581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2583 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2584 if ((*i)->id() == id) {
2589 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2592 /* Region management */
2595 Session::new_region_name (string old)
2597 string::size_type last_period;
2599 string::size_type len = old.length() + 64;
2602 if ((last_period = old.find_last_of ('.')) == string::npos) {
2604 /* no period present - add one explicitly */
2607 last_period = old.length() - 1;
2612 number = atoi (old.substr (last_period+1).c_str());
2616 while (number < (UINT_MAX-1)) {
2618 RegionList::const_iterator i;
2623 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2626 for (i = regions.begin(); i != regions.end(); ++i) {
2627 if (i->second->name() == sbuf) {
2632 if (i == regions.end()) {
2637 if (number != (UINT_MAX-1)) {
2641 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2646 Session::region_name (string& result, string base, bool newlevel) const
2651 assert(base.find("/") == string::npos);
2655 Glib::Mutex::Lock lm (region_lock);
2657 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2665 /* XXX this is going to be slow. optimize me later */
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);
2680 bool name_taken = true;
2683 Glib::Mutex::Lock lm (region_lock);
2685 for (int n = 1; n < 5000; ++n) {
2688 snprintf (buf, sizeof (buf), ".%d", n);
2693 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2694 if (i->second->name() == result) {
2707 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2715 Session::add_region (Region* region)
2720 Glib::Mutex::Lock lm (region_lock);
2722 RegionList::iterator x;
2724 for (x = regions.begin(); x != regions.end(); ++x) {
2726 if (region->region_list_equivalent (*x->second)) {
2731 if (x == regions.end()) {
2733 pair<RegionList::key_type,RegionList::mapped_type> entry;
2735 entry.first = region->id();
2736 entry.second = region;
2738 pair<RegionList::iterator,bool> x = regions.insert (entry);
2749 /* mark dirty because something has changed even if we didn't
2750 add the region to the region list.
2756 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2757 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2758 RegionAdded (region); /* EMIT SIGNAL */
2763 Session::region_changed (Change what_changed, Region* region)
2765 if (what_changed & Region::HiddenChanged) {
2766 /* relay hidden changes */
2767 RegionHiddenChange (region);
2772 Session::region_renamed (Region* region)
2774 add_region (region);
2778 Session::remove_region (Region* region)
2780 RegionList::iterator i;
2781 bool removed = false;
2784 Glib::Mutex::Lock lm (region_lock);
2786 if ((i = regions.find (region->id())) != regions.end()) {
2793 /* mark dirty because something has changed even if we didn't
2794 remove the region from the region list.
2800 RegionRemoved(region); /* EMIT SIGNAL */
2805 Session::find_whole_file_parent (Region& child)
2807 RegionList::iterator i;
2809 Glib::Mutex::Lock lm (region_lock);
2811 for (i = regions.begin(); i != regions.end(); ++i) {
2815 if (region->whole_file()) {
2817 if (child.source_equivalent (*region)) {
2827 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2829 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2830 (*i)->get_region_list_equivalent_regions (region, result);
2834 Session::destroy_region (Region* region)
2836 AudioRegion* aregion;
2838 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2842 if (aregion->playlist()) {
2843 aregion->playlist()->destroy_region (region);
2846 vector<Source*> srcs;
2848 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2849 srcs.push_back (&aregion->source (n));
2852 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2854 if ((*i)->use_cnt() == 0) {
2855 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2857 (afs)->mark_for_remove ();
2867 Session::destroy_regions (list<Region*> regions)
2869 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2870 destroy_region (*i);
2876 Session::remove_last_capture ()
2880 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2882 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2883 list<Region*>& l = (*i)->last_capture_regions();
2886 r.insert (r.end(), l.begin(), l.end());
2891 destroy_regions (r);
2896 Session::remove_region_from_region_list (Region& r)
2902 /* Source Management */
2904 Session::add_source (Source* source)
2906 pair<SourceList::key_type, SourceList::mapped_type> entry;
2909 Glib::Mutex::Lock lm (source_lock);
2910 entry.first = source->id();
2911 entry.second = source;
2912 sources.insert (entry);
2915 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2918 SourceAdded (source); /* EMIT SIGNAL */
2922 Session::remove_source (Source* source)
2924 SourceList::iterator i;
2927 Glib::Mutex::Lock lm (source_lock);
2929 if ((i = sources.find (source->id())) != sources.end()) {
2934 if (!_state_of_the_state & InCleanup) {
2936 /* save state so we don't end up with a session file
2937 referring to non-existent sources.
2940 save_state (_current_snapshot_name);
2943 SourceRemoved(source); /* EMIT SIGNAL */
2947 Session::source_by_id (const PBD::ID& id)
2949 Glib::Mutex::Lock lm (source_lock);
2950 SourceList::iterator i;
2953 if ((i = sources.find (id)) != sources.end()) {
2957 /* XXX search MIDI or other searches here */
2963 Session::peak_path_from_audio_path (string audio_path)
2965 /* XXX hardly bombproof! fix me */
2969 res = Glib::path_get_dirname (audio_path);
2970 res = Glib::path_get_dirname (res);
2972 res += peak_dir_name;
2974 res += PBD::basename_nosuffix (audio_path);
2981 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2984 string old_basename = PBD::basename_nosuffix (oldname);
2985 string new_legalized = legalize_for_path (newname);
2987 /* note: we know (or assume) the old path is already valid */
2991 /* destructive file sources have a name of the form:
2993 /path/to/Tnnnn-NAME(%[LR])?.wav
2995 the task here is to replace NAME with the new name.
2998 /* find last slash */
3002 string::size_type slash;
3003 string::size_type dash;
3005 if ((slash = path.find_last_of ('/')) == string::npos) {
3009 dir = path.substr (0, slash+1);
3011 /* '-' is not a legal character for the NAME part of the path */
3013 if ((dash = path.find_last_of ('-')) == string::npos) {
3017 prefix = path.substr (slash+1, dash-(slash+1));
3022 path += new_legalized;
3023 path += ".wav"; /* XXX gag me with a spoon */
3027 /* non-destructive file sources have a name of the form:
3029 /path/to/NAME-nnnnn(%[LR])?.wav
3031 the task here is to replace NAME with the new name.
3036 string::size_type slash;
3037 string::size_type dash;
3038 string::size_type postfix;
3040 /* find last slash */
3042 if ((slash = path.find_last_of ('/')) == string::npos) {
3046 dir = path.substr (0, slash+1);
3048 /* '-' is not a legal character for the NAME part of the path */
3050 if ((dash = path.find_last_of ('-')) == string::npos) {
3054 suffix = path.substr (dash+1);
3056 // Suffix is now everything after the dash. Now we need to eliminate
3057 // the nnnnn part, which is done by either finding a '%' or a '.'
3059 postfix = suffix.find_last_of ("%");
3060 if (postfix == string::npos) {
3061 postfix = suffix.find_last_of ('.');
3064 if (postfix != string::npos) {
3065 suffix = suffix.substr (postfix);
3067 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3071 const uint32_t limit = 10000;
3072 char buf[PATH_MAX+1];
3074 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3076 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3078 if (access (buf, F_OK) != 0) {
3086 error << "FATAL ERROR! Could not find a " << endl;
3095 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3099 char buf[PATH_MAX+1];
3100 const uint32_t limit = 10000;
3104 legalized = legalize_for_path (name);
3106 /* find a "version" of the file name that doesn't exist in
3107 any of the possible directories.
3110 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3112 vector<space_and_path>::iterator i;
3113 uint32_t existing = 0;
3115 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3120 spath += tape_dir_name;
3122 spath += sound_dir_name;
3127 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3128 } else if (nchan == 2) {
3130 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3132 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3134 } else if (nchan < 26) {
3135 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3137 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3145 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3146 } else if (nchan == 2) {
3148 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3150 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3152 } else if (nchan < 26) {
3153 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3155 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3159 if (access (buf, F_OK) == 0) {
3164 if (existing == 0) {
3169 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3170 throw failed_constructor();
3174 /* we now have a unique name for the file, but figure out where to
3181 spath = tape_dir ();
3183 spath = discover_best_sound_dir ();
3186 string::size_type pos = foo.find_last_of ('/');
3188 if (pos == string::npos) {
3191 spath += foo.substr (pos + 1);
3198 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3200 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3202 /* this might throw failed_constructor(), which is OK */
3205 return new DestructiveFileSource (spath,
3206 Config->get_native_file_data_format(),
3207 Config->get_native_file_header_format(),
3210 return new SndFileSource (spath,
3211 Config->get_native_file_data_format(),
3212 Config->get_native_file_header_format(),
3218 Session::midi_path_from_name (string name)
3222 char buf[PATH_MAX+1];
3223 const uint32_t limit = 10000;
3227 legalized = legalize_for_path (name);
3229 /* find a "version" of the file name that doesn't exist in
3230 any of the possible directories.
3233 for (cnt = 1; cnt <= limit; ++cnt) {
3235 vector<space_and_path>::iterator i;
3236 uint32_t existing = 0;
3238 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3240 // FIXME: different directory from audio?
3241 spath = (*i).path + sound_dir_name + "/" + legalized;
3243 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3245 if (access (buf, F_OK) == 0) {
3250 if (existing == 0) {
3255 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3256 throw failed_constructor();
3260 /* we now have a unique name for the file, but figure out where to
3266 // FIXME: different directory than audio?
3267 spath = discover_best_sound_dir ();
3269 string::size_type pos = foo.find_last_of ('/');
3271 if (pos == string::npos) {
3274 spath += foo.substr (pos + 1);
3281 Session::create_midi_source_for_session (MidiDiskstream& ds)
3283 string spath = midi_path_from_name (ds.name());
3285 /* this might throw failed_constructor(), which is OK */
3286 return new SMFSource (spath);
3290 /* Playlist management */
3293 Session::playlist_by_name (string name)
3295 Glib::Mutex::Lock lm (playlist_lock);
3296 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3297 if ((*i)->name() == name) {
3301 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3302 if ((*i)->name() == name) {
3310 Session::add_playlist (Playlist* playlist)
3312 if (playlist->hidden()) {
3317 Glib::Mutex::Lock lm (playlist_lock);
3318 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3319 playlists.insert (playlists.begin(), playlist);
3321 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3322 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3328 PlaylistAdded (playlist); /* EMIT SIGNAL */
3332 Session::track_playlist (Playlist* pl, bool inuse)
3334 PlaylistList::iterator x;
3337 Glib::Mutex::Lock lm (playlist_lock);
3340 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3342 unused_playlists.insert (pl);
3344 if ((x = playlists.find (pl)) != playlists.end()) {
3345 playlists.erase (x);
3350 //cerr << "shifting playlist to used: " << pl->name() << endl;
3352 playlists.insert (pl);
3354 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3355 unused_playlists.erase (x);
3362 Session::remove_playlist (Playlist* playlist)
3364 if (_state_of_the_state & Deletion) {
3369 Glib::Mutex::Lock lm (playlist_lock);
3370 // cerr << "removing playlist: " << playlist->name() << endl;
3372 PlaylistList::iterator i;
3374 i = find (playlists.begin(), playlists.end(), playlist);
3376 if (i != playlists.end()) {
3377 playlists.erase (i);
3380 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3381 if (i != unused_playlists.end()) {
3382 unused_playlists.erase (i);
3389 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3393 Session::set_audition (AudioRegion* r)
3395 pending_audition_region = r;
3396 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3397 schedule_butler_transport_work ();
3401 Session::non_realtime_set_audition ()
3403 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3404 auditioner->audition_current_playlist ();
3405 } else if (pending_audition_region) {
3406 auditioner->audition_region (*pending_audition_region);
3408 pending_audition_region = 0;
3409 AuditionActive (true); /* EMIT SIGNAL */
3413 Session::audition_playlist ()
3415 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3416 ev->set_ptr ((void*) 0xfeedface);
3421 Session::audition_region (Region& r)
3423 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3425 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3432 Session::cancel_audition ()
3434 if (auditioner->active()) {
3435 auditioner->cancel_audition ();
3436 AuditionActive (false); /* EMIT SIGNAL */
3441 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3443 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3447 Session::remove_empty_sounds ()
3450 PathScanner scanner;
3455 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3457 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3459 if (AudioFileSource::is_empty (*(*i))) {
3461 unlink ((*i)->c_str());
3463 string peak_path = peak_path_from_audio_path (**i);
3464 unlink (peak_path.c_str());
3470 delete possible_audiofiles;
3474 Session::is_auditioning () const
3476 /* can be called before we have an auditioner object */
3478 return auditioner->active();
3485 Session::set_all_solo (bool yn)
3487 shared_ptr<RouteList> r = routes.reader ();
3489 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3490 if (!(*i)->hidden()) {
3491 (*i)->set_solo (yn, this);
3499 Session::set_all_mute (bool yn)
3501 shared_ptr<RouteList> r = routes.reader ();
3503 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3504 if (!(*i)->hidden()) {
3505 (*i)->set_mute (yn, this);
3513 Session::n_diskstreams () const
3517 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3519 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3520 if (!(*i)->hidden()) {
3528 Session::graph_reordered ()
3530 /* don't do this stuff if we are setting up connections
3531 from a set_state() call.
3534 if (_state_of_the_state & InitialConnecting) {
3540 /* force all diskstreams to update their capture offset values to
3541 reflect any changes in latencies within the graph.
3544 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3546 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3547 (*i)->set_capture_offset ();
3552 Session::record_disenable_all ()
3554 record_enable_change_all (false);
3558 Session::record_enable_all ()
3560 record_enable_change_all (true);
3564 Session::record_enable_change_all (bool yn)
3566 shared_ptr<RouteList> r = routes.reader ();
3568 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3571 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3572 at->set_record_enable (yn, this);
3576 /* since we don't keep rec-enable state, don't mark session dirty */
3580 Session::add_redirect (Redirect* redirect)
3584 PortInsert* port_insert;
3585 PluginInsert* plugin_insert;
3587 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3588 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3589 _port_inserts.insert (_port_inserts.begin(), port_insert);
3590 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3591 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3593 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3596 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3597 _sends.insert (_sends.begin(), send);
3599 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3603 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3609 Session::remove_redirect (Redirect* redirect)
3613 PortInsert* port_insert;
3614 PluginInsert* plugin_insert;
3616 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3617 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3618 _port_inserts.remove (port_insert);
3619 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3620 _plugin_inserts.remove (plugin_insert);
3622 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3625 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3626 _sends.remove (send);
3628 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3636 Session::available_capture_duration ()
3638 const double scale = 4096.0 / sizeof (Sample);
3640 if (_total_free_4k_blocks * scale > (double) max_frames) {
3644 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3648 Session::add_connection (ARDOUR::Connection* connection)
3651 Glib::Mutex::Lock guard (connection_lock);
3652 _connections.push_back (connection);
3655 ConnectionAdded (connection); /* EMIT SIGNAL */
3661 Session::remove_connection (ARDOUR::Connection* connection)
3663 bool removed = false;
3666 Glib::Mutex::Lock guard (connection_lock);
3667 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3669 if (i != _connections.end()) {
3670 _connections.erase (i);
3676 ConnectionRemoved (connection); /* EMIT SIGNAL */
3682 ARDOUR::Connection *
3683 Session::connection_by_name (string name) const
3685 Glib::Mutex::Lock lm (connection_lock);
3687 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3688 if ((*i)->name() == name) {
3697 Session::set_edit_mode (EditMode mode)
3702 Glib::Mutex::Lock lm (playlist_lock);
3704 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3705 (*i)->set_edit_mode (mode);
3710 ControlChanged (EditingMode); /* EMIT SIGNAL */
3714 Session::tempo_map_changed (Change ignored)
3720 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3721 * the given count with the current block size.
3724 Session::ensure_buffers (ChanCount howmany)
3726 // FIXME: NASTY assumption (midi block size == audio block size)
3727 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3728 _send_buffers->ensure_buffers(howmany, current_block_size);
3729 _silent_buffers->ensure_buffers(howmany, current_block_size);
3731 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3735 Session::next_send_name ()
3738 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3743 Session::next_insert_name ()
3746 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3750 /* Named Selection management */
3753 Session::named_selection_by_name (string name)
3755 Glib::Mutex::Lock lm (named_selection_lock);
3756 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3757 if ((*i)->name == name) {
3765 Session::add_named_selection (NamedSelection* named_selection)
3768 Glib::Mutex::Lock lm (named_selection_lock);
3769 named_selections.insert (named_selections.begin(), named_selection);
3774 NamedSelectionAdded (); /* EMIT SIGNAL */
3778 Session::remove_named_selection (NamedSelection* named_selection)
3780 bool removed = false;
3783 Glib::Mutex::Lock lm (named_selection_lock);
3785 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3787 if (i != named_selections.end()) {
3789 named_selections.erase (i);
3796 NamedSelectionRemoved (); /* EMIT SIGNAL */
3801 Session::reset_native_file_format ()
3803 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3805 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3806 (*i)->reset_write_sources (false);
3811 Session::route_name_unique (string n) const
3813 shared_ptr<RouteList> r = routes.reader ();
3815 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3816 if ((*i)->name() == n) {
3825 Session::cleanup_audio_file_source (AudioFileSource& fs)
3827 return fs.move_to_trash (dead_sound_dir_name);
3831 Session::n_playlists () const
3833 Glib::Mutex::Lock lm (playlist_lock);
3834 return playlists.size();
3838 Session::set_solo_model (SoloModel sm)
3840 if (sm != _solo_model) {
3842 ControlChanged (SoloingModel);
3848 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3850 if (!force && howmany <= _npan_buffers) {
3854 if (_pan_automation_buffer) {
3856 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3857 delete [] _pan_automation_buffer[i];
3860 delete [] _pan_automation_buffer;
3863 _pan_automation_buffer = new pan_t*[howmany];
3865 for (uint32_t i = 0; i < howmany; ++i) {
3866 _pan_automation_buffer[i] = new pan_t[nframes];
3869 _npan_buffers = howmany;
3873 Session::freeze (InterThreadInfo& itt)
3875 shared_ptr<RouteList> r = routes.reader ();
3877 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3881 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3882 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3893 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3894 bool overwrite, vector<Source*>& srcs, InterThreadInfo& itt)
3897 Playlist* playlist = 0;
3898 AudioFileSource* fsource = 0;
3900 char buf[PATH_MAX+1];
3902 ChanCount nchans(track.audio_diskstream()->n_channels());
3903 jack_nframes_t position;
3904 jack_nframes_t this_chunk;
3905 jack_nframes_t to_do;
3908 // any bigger than this seems to cause stack overflows in called functions
3909 const jack_nframes_t chunk_size = (128 * 1024)/4;
3911 g_atomic_int_set (&processing_prohibited, 1);
3913 /* call tree *MUST* hold route_lock */
3915 if ((playlist = track.diskstream()->playlist()) == 0) {
3919 /* external redirects will be a problem */
3921 if (track.has_external_redirects()) {
3925 dir = discover_best_sound_dir ();
3927 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3929 for (x = 0; x < 99999; ++x) {
3930 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3931 if (access (buf, F_OK) != 0) {
3937 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3942 fsource = new SndFileSource (buf,
3943 Config->get_native_file_data_format(),
3944 Config->get_native_file_header_format(),
3949 catch (failed_constructor& err) {
3950 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3954 srcs.push_back(fsource);
3957 /* XXX need to flush all redirects */
3962 /* create a set of reasonably-sized buffers */
3963 buffers.ensure_buffers(nchans, chunk_size);
3964 buffers.set_count(nchans);
3966 while (to_do && !itt.cancel) {
3968 this_chunk = min (to_do, chunk_size);
3970 if (track.export_stuff (buffers, start, this_chunk)) {
3975 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3976 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3979 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
3985 start += this_chunk;
3986 to_do -= this_chunk;
3988 itt.progress = (float) (1.0 - ((double) to_do / len));
3997 xnow = localtime (&now);
3999 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4000 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
4002 afs->update_header (position, *xnow, now);
4006 /* build peakfile for new source */
4008 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4009 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
4011 afs->build_peaks ();
4020 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4021 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
4023 afs->mark_for_remove ();
4029 g_atomic_int_set (&processing_prohibited, 0);
4037 Session::get_silent_buffers (ChanCount count)
4039 assert(_silent_buffers->available() >= count);
4040 _silent_buffers->set_count(count);
4042 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4043 for (size_t i=0; i < count.get(*t); ++i) {
4044 _silent_buffers->get(*t, i).clear();
4048 return *_silent_buffers;
4052 Session::get_scratch_buffers (ChanCount count)
4054 assert(_scratch_buffers->available() >= count);
4055 _scratch_buffers->set_count(count);
4056 return *_scratch_buffers;
4060 Session::get_send_buffers (ChanCount count)
4062 assert(_send_buffers->available() >= count);
4063 _send_buffers->set_count(count);
4064 return *_send_buffers;
4068 Session::ntracks () const
4071 shared_ptr<RouteList> r = routes.reader ();
4073 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4074 if (dynamic_cast<Track*> ((*i).get())) {
4083 Session::nbusses () const
4086 shared_ptr<RouteList> r = routes.reader ();
4088 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4089 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4098 Session::set_layer_model (LayerModel lm)
4100 if (lm != layer_model) {
4103 ControlChanged (LayeringModel);
4108 Session::set_xfade_model (CrossfadeModel xm)
4110 if (xm != xfade_model) {
4113 ControlChanged (CrossfadingModel);
4118 Session::add_curve(Curve *curve)
4120 curves[curve->id()] = curve;
4124 Session::add_automation_list(AutomationList *al)
4126 automation_lists[al->id()] = al;