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/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
70 #include <ardour/osc.h>
76 using namespace ARDOUR;
78 using boost::shared_ptr;
80 const char* Session::_template_suffix = X_(".template");
81 const char* Session::_statefile_suffix = X_(".ardour");
82 const char* Session::_pending_suffix = X_(".pending");
83 const char* Session::sound_dir_name = X_("sounds");
84 const char* Session::tape_dir_name = X_("tapes");
85 const char* Session::peak_dir_name = X_("peaks");
86 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 Session::compute_peak_t Session::compute_peak = 0;
89 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
90 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
91 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
93 sigc::signal<int> Session::AskAboutPendingState;
94 sigc::signal<void> Session::SMPTEOffsetChanged;
95 sigc::signal<void> Session::SendFeedback;
99 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
102 char buf[PATH_MAX+1];
106 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
107 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
113 /* check to see if it exists, and what it is */
115 if (stat (str.c_str(), &statbuf)) {
116 if (errno == ENOENT) {
119 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
127 /* it exists, so it must either be the name
128 of the directory, or the name of the statefile
132 if (S_ISDIR (statbuf.st_mode)) {
134 string::size_type slash = str.find_last_of ('/');
136 if (slash == string::npos) {
138 /* a subdirectory of cwd, so statefile should be ... */
144 tmp += _statefile_suffix;
148 if (stat (tmp.c_str(), &statbuf)) {
149 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
159 /* some directory someplace in the filesystem.
160 the snapshot name is the directory name
165 snapshot = str.substr (slash+1);
169 } else if (S_ISREG (statbuf.st_mode)) {
171 string::size_type slash = str.find_last_of ('/');
172 string::size_type suffix;
174 /* remove the suffix */
176 if (slash != string::npos) {
177 snapshot = str.substr (slash+1);
182 suffix = snapshot.find (_statefile_suffix);
184 if (suffix == string::npos) {
185 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
191 snapshot = snapshot.substr (0, suffix);
193 if (slash == string::npos) {
195 /* we must be in the directory where the
196 statefile lives. get it using cwd().
199 char cwd[PATH_MAX+1];
201 if (getcwd (cwd, sizeof (cwd)) == 0) {
202 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
211 /* full path to the statefile */
213 path = str.substr (0, slash);
218 /* what type of file is it? */
219 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
225 /* its the name of a new directory. get the name
229 string::size_type slash = str.find_last_of ('/');
231 if (slash == string::npos) {
233 /* no slash, just use the name, but clean it up */
235 path = legalize_for_path (str);
241 snapshot = str.substr (slash+1);
248 Session::Session (AudioEngine &eng,
250 string snapshot_name,
251 string* mix_template)
254 _mmc_port (default_mmc_port),
255 _mtc_port (default_mtc_port),
256 _midi_port (default_midi_port),
257 pending_events (2048),
258 midi_requests (128), // the size of this should match the midi request pool size
259 diskstreams (new DiskstreamList),
260 routes (new RouteList),
261 auditioner ((Auditioner*) 0),
267 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
269 n_physical_outputs = _engine.n_physical_outputs();
270 n_physical_inputs = _engine.n_physical_inputs();
272 first_stage_init (fullpath, snapshot_name);
274 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
275 throw failed_constructor ();
278 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions(_name, _path);
284 bool was_dirty = dirty();
286 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
289 DirtyChanged (); /* EMIT SIGNAL */
293 Session::Session (AudioEngine &eng,
295 string snapshot_name,
296 AutoConnectOption input_ac,
297 AutoConnectOption output_ac,
298 uint32_t control_out_channels,
299 uint32_t master_out_channels,
300 uint32_t requested_physical_in,
301 uint32_t requested_physical_out,
302 jack_nframes_t initial_length)
305 _mmc_port (default_mmc_port),
306 _mtc_port (default_mtc_port),
307 _midi_port (default_midi_port),
308 pending_events (2048),
310 diskstreams (new DiskstreamList),
311 routes (new RouteList),
317 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
319 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
320 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
322 first_stage_init (fullpath, snapshot_name);
324 if (create (new_session, 0, initial_length)) {
325 throw failed_constructor ();
328 if (control_out_channels) {
329 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
336 if (master_out_channels) {
337 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
343 /* prohibit auto-connect to master, because there isn't one */
344 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
347 input_auto_connect = input_ac;
348 output_auto_connect = output_ac;
350 if (second_stage_init (new_session)) {
351 throw failed_constructor ();
354 store_recent_sessions(_name, _path);
356 bool was_dirty = dirty ();
358 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
361 DirtyChanged (); /* EMIT SIGNAL */
367 /* if we got to here, leaving pending capture state around
371 remove_pending_capture_state ();
373 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
374 _engine.remove_session ();
376 going_away (); /* EMIT SIGNAL */
378 terminate_butler_thread ();
379 terminate_midi_thread ();
381 if (click_data && click_data != default_click) {
382 delete [] click_data;
385 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
386 delete [] click_emphasis_data;
391 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
395 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
399 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
403 AudioDiskstream::free_working_buffers();
405 #undef TRACK_DESTRUCTION
406 #ifdef TRACK_DESTRUCTION
407 cerr << "delete named selections\n";
408 #endif /* TRACK_DESTRUCTION */
409 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
410 NamedSelectionList::iterator tmp;
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete playlists\n";
421 #endif /* TRACK_DESTRUCTION */
422 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
423 PlaylistList::iterator tmp;
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete audio regions\n";
435 #endif /* TRACK_DESTRUCTION */
436 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
437 AudioRegionList::iterator tmp;
447 #ifdef TRACK_DESTRUCTION
448 cerr << "delete routes\n";
449 #endif /* TRACK_DESTRUCTION */
451 RCUWriter<RouteList> writer (routes);
452 boost::shared_ptr<RouteList> r = writer.get_copy ();
453 for (RouteList::iterator i = r->begin(); i != r->end(); ) {
454 RouteList::iterator tmp;
457 (*i)->drop_references ();
461 /* writer goes out of scope and updates master */
466 #ifdef TRACK_DESTRUCTION
467 cerr << "delete diskstreams\n";
468 #endif /* TRACK_DESTRUCTION */
470 RCUWriter<DiskstreamList> dwriter (diskstreams);
471 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
472 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
473 DiskstreamList::iterator tmp;
478 (*i)->drop_references ();
484 diskstreams.flush ();
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete audio sources\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
490 AudioSourceList::iterator tmp;
500 #ifdef TRACK_DESTRUCTION
501 cerr << "delete mix groups\n";
502 #endif /* TRACK_DESTRUCTION */
503 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
504 list<RouteGroup*>::iterator tmp;
514 #ifdef TRACK_DESTRUCTION
515 cerr << "delete edit groups\n";
516 #endif /* TRACK_DESTRUCTION */
517 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
518 list<RouteGroup*>::iterator tmp;
528 #ifdef TRACK_DESTRUCTION
529 cerr << "delete connections\n";
530 #endif /* TRACK_DESTRUCTION */
531 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
532 ConnectionList::iterator tmp;
542 if (butler_mixdown_buffer) {
543 delete [] butler_mixdown_buffer;
546 if (butler_gain_buffer) {
547 delete [] butler_gain_buffer;
550 Crossfade::set_buffer_size (0);
562 Session::set_worst_io_latencies ()
564 _worst_output_latency = 0;
565 _worst_input_latency = 0;
567 if (!_engine.connected()) {
571 boost::shared_ptr<RouteList> r = routes.reader ();
573 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
574 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
575 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
580 Session::when_engine_running ()
582 string first_physical_output;
584 /* we don't want to run execute this again */
586 first_time_running.disconnect ();
588 set_block_size (_engine.frames_per_cycle());
589 set_frame_rate (_engine.frame_rate());
591 /* every time we reconnect, recompute worst case output latencies */
593 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
595 if (synced_to_jack()) {
596 _engine.transport_stop ();
599 if (Config->get_jack_time_master()) {
600 _engine.transport_locate (_transport_frame);
608 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
610 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
612 /* existing state for Click */
614 if (_click_io->set_state (*child->children().front()) == 0) {
616 _clicking = click_requested;
620 error << _("could not setup Click I/O") << endmsg;
626 /* default state for Click */
628 first_physical_output = _engine.get_nth_physical_output (0);
630 if (first_physical_output.length()) {
631 if (_click_io->add_output_port (first_physical_output, this)) {
632 // relax, even though its an error
634 _clicking = click_requested;
640 catch (failed_constructor& err) {
641 error << _("cannot setup Click I/O") << endmsg;
644 set_worst_io_latencies ();
647 ControlChanged (Clicking); /* EMIT SIGNAL */
650 if (auditioner == 0) {
652 /* we delay creating the auditioner till now because
653 it makes its own connections to ports named
654 in the ARDOUR_RC config file. the engine has
655 to be running for this to work.
659 auditioner.reset (new Auditioner (*this));
662 catch (failed_constructor& err) {
663 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
667 /* Create a set of Connection objects that map
668 to the physical outputs currently available
673 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
675 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
677 Connection* c = new OutputConnection (buf, true);
680 c->add_connection (0, _engine.get_nth_physical_output (np));
685 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
687 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
689 Connection* c = new InputConnection (buf, true);
692 c->add_connection (0, _engine.get_nth_physical_input (np));
699 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
701 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
703 Connection* c = new OutputConnection (buf, true);
707 c->add_connection (0, _engine.get_nth_physical_output (np));
708 c->add_connection (1, _engine.get_nth_physical_output (np+1));
713 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
715 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
717 Connection* c = new InputConnection (buf, true);
721 c->add_connection (0, _engine.get_nth_physical_input (np));
722 c->add_connection (1, _engine.get_nth_physical_input (np+1));
731 /* create master/control ports */
736 /* force the master to ignore any later call to this */
738 if (_master_out->pending_state_node) {
739 _master_out->ports_became_legal();
742 /* no panner resets till we are through */
744 _master_out->defer_pan_reset ();
746 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
747 if (_master_out->add_input_port ("", this)) {
748 error << _("cannot setup master inputs")
754 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
755 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
756 error << _("cannot setup master outputs")
763 _master_out->allow_pan_reset ();
767 Connection* c = new OutputConnection (_("Master Out"), true);
769 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
771 c->add_connection ((int) n, _master_out->input(n)->name());
778 /* catch up on send+insert cnts */
782 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
785 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
786 if (id > insert_cnt) {
794 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
797 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
804 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
806 /* hook us up to the engine */
808 _engine.set_session (this);
813 osc->set_session (*this);
816 _state_of_the_state = Clean;
818 DirtyChanged (); /* EMIT SIGNAL */
822 Session::hookup_io ()
824 /* stop graph reordering notifications from
825 causing resorts, etc.
828 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
830 /* Tell all IO objects to create their ports */
837 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
838 if (_control_out->add_input_port ("", this)) {
839 error << _("cannot setup control inputs")
845 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
846 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
847 error << _("cannot set up master outputs")
855 /* Tell all IO objects to connect themselves together */
857 IO::enable_connecting ();
859 /* Now reset all panners */
861 IO::reset_panners ();
863 /* Anyone who cares about input state, wake up and do something */
865 IOConnectionsComplete (); /* EMIT SIGNAL */
867 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
869 /* now handle the whole enchilada as if it was one
875 /* update mixer solo state */
881 Session::playlist_length_changed (Playlist* pl)
883 /* we can't just increase end_location->end() if pl->get_maximum_extent()
884 if larger. if the playlist used to be the longest playlist,
885 and its now shorter, we have to decrease end_location->end(). hence,
886 we have to iterate over all diskstreams and check the
887 playlists currently in use.
893 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
897 if ((playlist = dstream->playlist()) != 0) {
898 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
901 /* see comment in playlist_length_changed () */
906 Session::record_enabling_legal () const
908 /* this used to be in here, but survey says.... we don't need to restrict it */
909 // if (record_status() == Recording) {
920 Session::set_auto_play (bool yn)
922 if (auto_play != yn) {
925 ControlChanged (AutoPlay);
930 Session::set_auto_return (bool yn)
932 if (auto_return != yn) {
935 ControlChanged (AutoReturn);
940 Session::set_crossfades_active (bool yn)
942 if (crossfades_active != yn) {
943 crossfades_active = yn;
945 ControlChanged (CrossFadesActive);
950 Session::set_do_not_record_plugins (bool yn)
952 if (do_not_record_plugins != yn) {
953 do_not_record_plugins = yn;
955 ControlChanged (RecordingPlugins);
960 Session::set_auto_input (bool yn)
962 if (auto_input != yn) {
965 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
966 /* auto-input only makes a difference if we're rolling */
968 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
970 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
971 if ((*i)->record_enabled ()) {
972 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
973 (*i)->monitor_input (!auto_input);
979 ControlChanged (AutoInput);
984 Session::reset_input_monitor_state ()
986 if (transport_rolling()) {
988 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
990 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
991 if ((*i)->record_enabled ()) {
992 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
993 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
999 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1000 if ((*i)->record_enabled ()) {
1001 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1002 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1010 Session::set_input_auto_connect (bool yn)
1013 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1015 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1021 Session::get_input_auto_connect () const
1023 return (input_auto_connect & AutoConnectPhysical);
1027 Session::set_output_auto_connect (AutoConnectOption aco)
1029 output_auto_connect = aco;
1034 Session::auto_punch_start_changed (Location* location)
1036 replace_event (Event::PunchIn, location->start());
1038 if (get_record_enabled() && get_punch_in()) {
1039 /* capture start has been changed, so save new pending state */
1040 save_state ("", true);
1045 Session::auto_punch_end_changed (Location* location)
1047 jack_nframes_t when_to_stop = location->end();
1048 // when_to_stop += _worst_output_latency + _worst_input_latency;
1049 replace_event (Event::PunchOut, when_to_stop);
1053 Session::auto_punch_changed (Location* location)
1055 jack_nframes_t when_to_stop = location->end();
1057 replace_event (Event::PunchIn, location->start());
1058 //when_to_stop += _worst_output_latency + _worst_input_latency;
1059 replace_event (Event::PunchOut, when_to_stop);
1063 Session::auto_loop_changed (Location* location)
1065 replace_event (Event::AutoLoop, location->end(), location->start());
1067 if (transport_rolling() && get_auto_loop()) {
1069 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1071 if (_transport_frame > location->end()) {
1072 // relocate to beginning of loop
1073 clear_events (Event::LocateRoll);
1075 request_locate (location->start(), true);
1078 else if (seamless_loop && !loop_changing) {
1080 // schedule a locate-roll to refill the diskstreams at the
1081 // previous loop end
1082 loop_changing = true;
1084 if (location->end() > last_loopend) {
1085 clear_events (Event::LocateRoll);
1086 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1093 last_loopend = location->end();
1098 Session::set_auto_punch_location (Location* location)
1102 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1103 auto_punch_start_changed_connection.disconnect();
1104 auto_punch_end_changed_connection.disconnect();
1105 auto_punch_changed_connection.disconnect();
1106 existing->set_auto_punch (false, this);
1107 remove_event (existing->start(), Event::PunchIn);
1108 clear_events (Event::PunchOut);
1109 auto_punch_location_changed (0);
1114 if (location == 0) {
1118 if (location->end() <= location->start()) {
1119 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1123 auto_punch_start_changed_connection.disconnect();
1124 auto_punch_end_changed_connection.disconnect();
1125 auto_punch_changed_connection.disconnect();
1127 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1128 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1129 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1131 location->set_auto_punch (true, this);
1132 auto_punch_location_changed (location);
1136 Session::set_punch_in (bool yn)
1138 if (punch_in == yn) {
1144 if ((location = _locations.auto_punch_location()) != 0) {
1145 if ((punch_in = yn) == true) {
1146 replace_event (Event::PunchIn, location->start());
1148 remove_event (location->start(), Event::PunchIn);
1153 ControlChanged (PunchIn); /* EMIT SIGNAL */
1157 Session::set_punch_out (bool yn)
1159 if (punch_out == yn) {
1165 if ((location = _locations.auto_punch_location()) != 0) {
1166 if ((punch_out = yn) == true) {
1167 replace_event (Event::PunchOut, location->end());
1169 clear_events (Event::PunchOut);
1174 ControlChanged (PunchOut); /* EMIT SIGNAL */
1178 Session::set_auto_loop_location (Location* location)
1182 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1183 auto_loop_start_changed_connection.disconnect();
1184 auto_loop_end_changed_connection.disconnect();
1185 auto_loop_changed_connection.disconnect();
1186 existing->set_auto_loop (false, this);
1187 remove_event (existing->end(), Event::AutoLoop);
1188 auto_loop_location_changed (0);
1193 if (location == 0) {
1197 if (location->end() <= location->start()) {
1198 error << _("Session: you can't use a mark for auto loop") << endmsg;
1202 last_loopend = location->end();
1204 auto_loop_start_changed_connection.disconnect();
1205 auto_loop_end_changed_connection.disconnect();
1206 auto_loop_changed_connection.disconnect();
1208 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1209 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1210 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1212 location->set_auto_loop (true, this);
1213 auto_loop_location_changed (location);
1217 Session::locations_added (Location* ignored)
1223 Session::locations_changed ()
1225 _locations.apply (*this, &Session::handle_locations_changed);
1229 Session::handle_locations_changed (Locations::LocationList& locations)
1231 Locations::LocationList::iterator i;
1233 bool set_loop = false;
1234 bool set_punch = false;
1236 for (i = locations.begin(); i != locations.end(); ++i) {
1240 if (location->is_auto_punch()) {
1241 set_auto_punch_location (location);
1244 if (location->is_auto_loop()) {
1245 set_auto_loop_location (location);
1252 set_auto_loop_location (0);
1255 set_auto_punch_location (0);
1262 Session::enable_record ()
1264 /* XXX really atomic compare+swap here */
1265 if (g_atomic_int_get (&_record_status) != Recording) {
1266 g_atomic_int_set (&_record_status, Recording);
1267 _last_record_location = _transport_frame;
1268 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1270 if (Config->get_use_hardware_monitoring() && auto_input) {
1271 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1272 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1273 if ((*i)->record_enabled ()) {
1274 (*i)->monitor_input (true);
1279 RecordStateChanged ();
1284 Session::disable_record (bool rt_context, bool force)
1288 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1290 if (!Config->get_latched_record_enable () || force) {
1291 g_atomic_int_set (&_record_status, Disabled);
1293 if (rs == Recording) {
1294 g_atomic_int_set (&_record_status, Enabled);
1298 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1300 if (Config->get_use_hardware_monitoring() && auto_input) {
1301 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1303 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1304 if ((*i)->record_enabled ()) {
1305 (*i)->monitor_input (false);
1310 RecordStateChanged (); /* emit signal */
1313 remove_pending_capture_state ();
1319 Session::step_back_from_record ()
1321 g_atomic_int_set (&_record_status, Enabled);
1323 if (Config->get_use_hardware_monitoring()) {
1324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1327 if (auto_input && (*i)->record_enabled ()) {
1328 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1329 (*i)->monitor_input (false);
1336 Session::maybe_enable_record ()
1338 g_atomic_int_set (&_record_status, Enabled);
1340 /* XXX this save should really happen in another thread. its needed so that
1341 pending capture state can be recovered if we crash.
1344 save_state ("", true);
1346 if (_transport_speed) {
1351 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1352 RecordStateChanged (); /* EMIT SIGNAL */
1359 Session::audible_frame () const
1362 jack_nframes_t offset;
1365 /* the first of these two possible settings for "offset"
1366 mean that the audible frame is stationary until
1367 audio emerges from the latency compensation
1370 the second means that the audible frame is stationary
1371 until audio would emerge from a physical port
1372 in the absence of any plugin latency compensation
1375 offset = _worst_output_latency;
1377 if (offset > current_block_size) {
1378 offset -= current_block_size;
1380 /* XXX is this correct? if we have no external
1381 physical connections and everything is internal
1382 then surely this is zero? still, how
1383 likely is that anyway?
1385 offset = current_block_size;
1388 if (synced_to_jack()) {
1389 tf = _engine.transport_frame();
1391 tf = _transport_frame;
1394 if (_transport_speed == 0) {
1404 if (!non_realtime_work_pending()) {
1408 /* take latency into account */
1417 Session::set_frame_rate (jack_nframes_t frames_per_second)
1419 /** \fn void Session::set_frame_size(jack_nframes_t)
1420 the AudioEngine object that calls this guarantees
1421 that it will not be called while we are also in
1422 ::process(). Its fine to do things that block
1426 _current_frame_rate = frames_per_second;
1427 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1429 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1431 // XXX we need some equivalent to this, somehow
1432 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1436 /* XXX need to reset/reinstantiate all LADSPA plugins */
1440 Session::set_block_size (jack_nframes_t nframes)
1442 /* the AudioEngine guarantees
1443 that it will not be called while we are also in
1444 ::process(). It is therefore fine to do things that block
1449 vector<Sample*>::iterator i;
1452 current_block_size = nframes;
1454 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1458 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1462 _passthru_buffers.clear ();
1463 _silent_buffers.clear ();
1465 ensure_passthru_buffers (np);
1467 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1471 #ifdef NO_POSIX_MEMALIGN
1472 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1474 posix_memalign((void **)&buf,16,current_block_size * 4);
1478 memset (*i, 0, sizeof (Sample) * current_block_size);
1482 if (_gain_automation_buffer) {
1483 delete [] _gain_automation_buffer;
1485 _gain_automation_buffer = new gain_t[nframes];
1487 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1489 boost::shared_ptr<RouteList> r = routes.reader ();
1491 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1492 (*i)->set_block_size (nframes);
1495 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1497 (*i)->set_block_size (nframes);
1500 set_worst_io_latencies ();
1505 Session::set_default_fade (float steepness, float fade_msecs)
1508 jack_nframes_t fade_frames;
1510 /* Don't allow fade of less 1 frame */
1512 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1519 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1523 default_fade_msecs = fade_msecs;
1524 default_fade_steepness = steepness;
1527 // jlc, WTF is this!
1528 Glib::RWLock::ReaderLock lm (route_lock);
1529 AudioRegion::set_default_fade (steepness, fade_frames);
1534 /* XXX have to do this at some point */
1535 /* foreach region using default fade, reset, then
1536 refill_all_diskstream_buffers ();
1541 struct RouteSorter {
1542 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1543 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1545 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1548 if (r1->fed_by.empty()) {
1549 if (r2->fed_by.empty()) {
1550 /* no ardour-based connections inbound to either route. just use signal order */
1551 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1553 /* r2 has connections, r1 does not; run r1 early */
1557 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1564 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1566 shared_ptr<Route> r2;
1568 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1569 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1573 /* make a copy of the existing list of routes that feed r1 */
1575 set<shared_ptr<Route> > existing = r1->fed_by;
1577 /* for each route that feeds r1, recurse, marking it as feeding
1581 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1584 /* r2 is a route that feeds r1 which somehow feeds base. mark
1585 base as being fed by r2
1588 rbase->fed_by.insert (r2);
1592 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1596 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1600 /* now recurse, so that we can mark base as being fed by
1601 all routes that feed r2
1604 trace_terminal (r2, rbase);
1611 Session::resort_routes ()
1613 /* don't do anything here with signals emitted
1614 by Routes while we are being destroyed.
1617 if (_state_of_the_state & Deletion) {
1624 RCUWriter<RouteList> writer (routes);
1625 shared_ptr<RouteList> r = writer.get_copy ();
1626 resort_routes_using (r);
1627 /* writer goes out of scope and forces update */
1632 Session::resort_routes_using (shared_ptr<RouteList> r)
1634 RouteList::iterator i, j;
1636 for (i = r->begin(); i != r->end(); ++i) {
1638 (*i)->fed_by.clear ();
1640 for (j = r->begin(); j != r->end(); ++j) {
1642 /* although routes can feed themselves, it will
1643 cause an endless recursive descent if we
1644 detect it. so don't bother checking for
1652 if ((*j)->feeds (*i)) {
1653 (*i)->fed_by.insert (*j);
1658 for (i = r->begin(); i != r->end(); ++i) {
1659 trace_terminal (*i, *i);
1666 cerr << "finished route resort\n";
1668 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1669 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1676 list<boost::shared_ptr<AudioTrack> >
1677 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1679 char track_name[32];
1680 uint32_t track_id = 0;
1682 uint32_t channels_used = 0;
1684 RouteList new_routes;
1685 list<boost::shared_ptr<AudioTrack> > ret;
1687 /* count existing audio tracks */
1690 shared_ptr<RouteList> r = routes.reader ();
1692 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1693 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1694 if (!(*i)->hidden()) {
1696 channels_used += (*i)->n_inputs();
1702 vector<string> physinputs;
1703 vector<string> physoutputs;
1704 uint32_t nphysical_in;
1705 uint32_t nphysical_out;
1707 _engine.get_physical_outputs (physoutputs);
1708 _engine.get_physical_inputs (physinputs);
1712 /* check for duplicate route names, since we might have pre-existing
1713 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1714 save, close,restart,add new route - first named route is now
1722 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1724 if (route_by_name (track_name) == 0) {
1728 } while (track_id < (UINT_MAX-1));
1730 if (input_auto_connect & AutoConnectPhysical) {
1731 nphysical_in = min (n_physical_inputs, physinputs.size());
1736 if (output_auto_connect & AutoConnectPhysical) {
1737 nphysical_out = min (n_physical_outputs, physinputs.size());
1743 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1745 if (track->ensure_io (input_channels, output_channels, false, this)) {
1746 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1747 input_channels, output_channels)
1752 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1756 if (input_auto_connect & AutoConnectPhysical) {
1757 port = physinputs[(channels_used+x)%nphysical_in];
1760 if (port.length() && track->connect_input (track->input (x), port, this)) {
1766 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1770 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1771 port = physoutputs[(channels_used+x)%nphysical_out];
1772 } else if (output_auto_connect & AutoConnectMaster) {
1774 port = _master_out->input (x%_master_out->n_inputs())->name();
1778 if (port.length() && track->connect_output (track->output (x), port, this)) {
1783 channels_used += track->n_inputs ();
1786 vector<string> cports;
1787 uint32_t ni = _control_out->n_inputs();
1789 for (n = 0; n < ni; ++n) {
1790 cports.push_back (_control_out->input(n)->name());
1793 track->set_control_outs (cports);
1796 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1797 track->set_remote_control_id (ntracks());
1799 new_routes.push_back (track);
1800 ret.push_back (track);
1803 catch (failed_constructor &err) {
1804 error << _("Session: could not create new audio track.") << endmsg;
1805 // XXX should we delete the tracks already created?
1813 if (!new_routes.empty()) {
1814 add_routes (new_routes, false);
1815 save_state (_current_snapshot_name);
1822 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1825 uint32_t bus_id = 1;
1830 /* count existing audio busses */
1833 shared_ptr<RouteList> r = routes.reader ();
1835 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1836 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1837 if (!(*i)->hidden()) {
1844 vector<string> physinputs;
1845 vector<string> physoutputs;
1847 _engine.get_physical_outputs (physoutputs);
1848 _engine.get_physical_inputs (physinputs);
1855 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1857 if (route_by_name (bus_name) == 0) {
1861 } while (bus_id < (UINT_MAX-1));
1864 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1866 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1867 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1868 input_channels, output_channels)
1872 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1876 if (input_auto_connect & AutoConnectPhysical) {
1877 port = physinputs[((n+x)%n_physical_inputs)];
1880 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1885 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1889 if (output_auto_connect & AutoConnectPhysical) {
1890 port = physoutputs[((n+x)%n_physical_outputs)];
1891 } else if (output_auto_connect & AutoConnectMaster) {
1893 port = _master_out->input (x%_master_out->n_inputs())->name();
1897 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1903 vector<string> cports;
1904 uint32_t ni = _control_out->n_inputs();
1906 for (uint32_t n = 0; n < ni; ++n) {
1907 cports.push_back (_control_out->input(n)->name());
1909 bus->set_control_outs (cports);
1912 ret.push_back (bus);
1916 catch (failed_constructor &err) {
1917 error << _("Session: could not create new audio route.") << endmsg;
1926 add_routes (ret, false);
1927 save_state (_current_snapshot_name);
1935 Session::add_routes (RouteList& new_routes, bool save)
1938 RCUWriter<RouteList> writer (routes);
1939 shared_ptr<RouteList> r = writer.get_copy ();
1940 r->insert (r->end(), new_routes.begin(), new_routes.end());
1941 resort_routes_using (r);
1944 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1945 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1946 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1947 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1948 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1950 if ((*x)->master()) {
1954 if ((*x)->control()) {
1955 _control_out = (*x);
1962 save_state (_current_snapshot_name);
1965 RouteAdded (new_routes); /* EMIT SIGNAL */
1969 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1971 /* need to do this in case we're rolling at the time, to prevent false underruns */
1972 dstream->do_refill_with_alloc();
1975 RCUWriter<DiskstreamList> writer (diskstreams);
1976 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1977 ds->push_back (dstream);
1980 dstream->set_block_size (current_block_size);
1982 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1983 /* this will connect to future changes, and check the current length */
1984 diskstream_playlist_changed (dstream);
1986 dstream->prepare ();
1990 Session::remove_route (shared_ptr<Route> route)
1993 RCUWriter<RouteList> writer (routes);
1994 shared_ptr<RouteList> rs = writer.get_copy ();
1997 /* deleting the master out seems like a dumb
1998 idea, but its more of a UI policy issue
2002 if (route == _master_out) {
2003 _master_out = shared_ptr<Route> ((Route*) 0);
2006 if (route == _control_out) {
2007 _control_out = shared_ptr<Route> ((Route*) 0);
2009 /* cancel control outs for all routes */
2011 vector<string> empty;
2013 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2014 (*r)->set_control_outs (empty);
2018 update_route_solo_state ();
2020 /* writer goes out of scope, forces route list update */
2023 // FIXME: audio specific
2025 boost::shared_ptr<AudioDiskstream> ds;
2027 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2028 ds = at->audio_diskstream();
2034 RCUWriter<DiskstreamList> dsl (diskstreams);
2035 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2040 find_current_end ();
2042 update_latency_compensation (false, false);
2045 /* XXX should we disconnect from the Route's signals ? */
2047 save_state (_current_snapshot_name);
2049 /* try to cause everyone to drop their references */
2051 route->drop_references ();
2055 Session::route_mute_changed (void* src)
2061 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2063 if (solo_update_disabled) {
2070 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2072 shared_ptr<RouteList> r = routes.reader ();
2074 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2080 /* don't mess with busses */
2082 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2088 /* don't mess with tracks */
2090 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2095 if ((*i) != route &&
2096 ((*i)->mix_group () == 0 ||
2097 (*i)->mix_group () != route->mix_group () ||
2098 !route->mix_group ()->is_active())) {
2100 if ((*i)->soloed()) {
2102 /* if its already soloed, and solo latching is enabled,
2103 then leave it as it is.
2106 if (_solo_latched) {
2113 solo_update_disabled = true;
2114 (*i)->set_solo (false, src);
2115 solo_update_disabled = false;
2119 bool something_soloed = false;
2120 bool same_thing_soloed = false;
2121 bool signal = false;
2123 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2124 if ((*i)->soloed()) {
2125 something_soloed = true;
2126 if (dynamic_cast<AudioTrack*>((*i).get())) {
2128 same_thing_soloed = true;
2133 same_thing_soloed = true;
2141 if (something_soloed != currently_soloing) {
2143 currently_soloing = something_soloed;
2146 modify_solo_mute (is_track, same_thing_soloed);
2149 SoloActive (currently_soloing);
2156 Session::set_solo_latched (bool yn)
2158 if (yn != _solo_latched) {
2161 ControlChanged (SoloLatch);
2166 Session::update_route_solo_state ()
2169 bool is_track = false;
2170 bool signal = false;
2172 /* caller must hold RouteLock */
2174 /* this is where we actually implement solo by changing
2175 the solo mute setting of each track.
2178 shared_ptr<RouteList> r = routes.reader ();
2180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2181 if ((*i)->soloed()) {
2183 if (dynamic_cast<AudioTrack*>((*i).get())) {
2190 if (mute != currently_soloing) {
2192 currently_soloing = mute;
2195 if (!is_track && !mute) {
2197 /* nothing is soloed */
2199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2200 (*i)->set_solo_mute (false);
2210 modify_solo_mute (is_track, mute);
2213 SoloActive (currently_soloing);
2218 Session::modify_solo_mute (bool is_track, bool mute)
2220 shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 /* only alter track solo mute */
2228 if (dynamic_cast<AudioTrack*>((*i).get())) {
2229 if ((*i)->soloed()) {
2230 (*i)->set_solo_mute (!mute);
2232 (*i)->set_solo_mute (mute);
2238 /* only alter bus solo mute */
2240 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2242 if ((*i)->soloed()) {
2244 (*i)->set_solo_mute (false);
2248 /* don't mute master or control outs
2249 in response to another bus solo
2252 if ((*i) != _master_out &&
2253 (*i) != _control_out) {
2254 (*i)->set_solo_mute (mute);
2265 Session::catch_up_on_solo ()
2267 /* this is called after set_state() to catch the full solo
2268 state, which can't be correctly determined on a per-route
2269 basis, but needs the global overview that only the session
2272 update_route_solo_state();
2276 Session::route_by_name (string name)
2278 shared_ptr<RouteList> r = routes.reader ();
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((*i)->name() == name) {
2286 return shared_ptr<Route> ((Route*) 0);
2290 Session::route_by_id (PBD::ID id)
2292 shared_ptr<RouteList> r = routes.reader ();
2294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2295 if ((*i)->id() == id) {
2300 return shared_ptr<Route> ((Route*) 0);
2304 Session::route_by_remote_id (uint32_t id)
2306 shared_ptr<RouteList> r = routes.reader ();
2308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 if ((*i)->remote_control_id() == id) {
2314 return shared_ptr<Route> ((Route*) 0);
2318 Session::find_current_end ()
2320 if (_state_of_the_state & Loading) {
2324 jack_nframes_t max = get_maximum_extent ();
2326 if (max > end_location->end()) {
2327 end_location->set_end (max);
2329 DurationChanged(); /* EMIT SIGNAL */
2334 Session::get_maximum_extent () const
2336 jack_nframes_t max = 0;
2339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2341 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2342 Playlist* pl = (*i)->playlist();
2343 if ((me = pl->get_maximum_extent()) > max) {
2351 boost::shared_ptr<Diskstream>
2352 Session::diskstream_by_name (string name)
2354 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2356 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2357 if ((*i)->name() == name) {
2362 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2365 boost::shared_ptr<Diskstream>
2366 Session::diskstream_by_id (const PBD::ID& id)
2368 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2371 if ((*i)->id() == id) {
2376 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2379 /* AudioRegion management */
2382 Session::new_region_name (string old)
2384 string::size_type last_period;
2386 string::size_type len = old.length() + 64;
2389 if ((last_period = old.find_last_of ('.')) == string::npos) {
2391 /* no period present - add one explicitly */
2394 last_period = old.length() - 1;
2399 number = atoi (old.substr (last_period+1).c_str());
2403 while (number < (UINT_MAX-1)) {
2405 AudioRegionList::const_iterator i;
2410 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2413 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2414 if (i->second->name() == sbuf) {
2419 if (i == audio_regions.end()) {
2424 if (number != (UINT_MAX-1)) {
2428 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2433 Session::region_name (string& result, string base, bool newlevel) const
2440 Glib::Mutex::Lock lm (region_lock);
2442 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2450 /* XXX this is going to be slow. optimize me later */
2455 string::size_type pos;
2457 pos = base.find_last_of ('.');
2459 /* pos may be npos, but then we just use entire base */
2461 subbase = base.substr (0, pos);
2465 bool name_taken = true;
2468 Glib::Mutex::Lock lm (region_lock);
2470 for (int n = 1; n < 5000; ++n) {
2473 snprintf (buf, sizeof (buf), ".%d", n);
2478 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2479 if (i->second->name() == result) {
2492 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2500 Session::add_region (Region* region)
2502 AudioRegion* ar = 0;
2503 AudioRegion* oar = 0;
2507 Glib::Mutex::Lock lm (region_lock);
2509 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2511 AudioRegionList::iterator x;
2513 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2515 oar = dynamic_cast<AudioRegion*> (x->second);
2517 if (ar->region_list_equivalent (*oar)) {
2522 if (x == audio_regions.end()) {
2524 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2526 entry.first = region->id();
2529 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2540 fatal << _("programming error: ")
2541 << X_("unknown region type passed to Session::add_region()")
2548 /* mark dirty because something has changed even if we didn't
2549 add the region to the region list.
2555 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2556 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2557 AudioRegionAdded (ar); /* EMIT SIGNAL */
2562 Session::region_changed (Change what_changed, Region* region)
2564 if (what_changed & Region::HiddenChanged) {
2565 /* relay hidden changes */
2566 RegionHiddenChange (region);
2571 Session::region_renamed (Region* region)
2573 add_region (region);
2577 Session::remove_region (Region* region)
2579 AudioRegionList::iterator i;
2580 AudioRegion* ar = 0;
2581 bool removed = false;
2584 Glib::Mutex::Lock lm (region_lock);
2586 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2587 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2588 audio_regions.erase (i);
2594 fatal << _("programming error: ")
2595 << X_("unknown region type passed to Session::remove_region()")
2601 /* mark dirty because something has changed even if we didn't
2602 remove the region from the region list.
2608 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2613 Session::find_whole_file_parent (AudioRegion& child)
2615 AudioRegionList::iterator i;
2616 AudioRegion* region;
2617 Glib::Mutex::Lock lm (region_lock);
2619 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2623 if (region->whole_file()) {
2625 if (child.source_equivalent (*region)) {
2635 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2637 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2638 (*i)->get_region_list_equivalent_regions (region, result);
2642 Session::destroy_region (Region* region)
2644 AudioRegion* aregion;
2646 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2650 if (aregion->playlist()) {
2651 aregion->playlist()->destroy_region (region);
2654 vector<Source*> srcs;
2656 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2657 srcs.push_back (&aregion->source (n));
2660 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2662 if ((*i)->use_cnt() == 0) {
2663 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2665 (afs)->mark_for_remove ();
2675 Session::destroy_regions (list<Region*> regions)
2677 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2678 destroy_region (*i);
2684 Session::remove_last_capture ()
2688 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2690 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2691 list<Region*>& l = (*i)->last_capture_regions();
2694 r.insert (r.end(), l.begin(), l.end());
2699 destroy_regions (r);
2704 Session::remove_region_from_region_list (Region& r)
2710 /* Source Management */
2713 Session::add_audio_source (AudioSource* source)
2715 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2718 Glib::Mutex::Lock lm (audio_source_lock);
2719 entry.first = source->id();
2720 entry.second = source;
2721 audio_sources.insert (entry);
2724 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2727 SourceAdded (source); /* EMIT SIGNAL */
2731 Session::remove_source (Source* source)
2733 AudioSourceList::iterator i;
2736 Glib::Mutex::Lock lm (audio_source_lock);
2738 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2739 audio_sources.erase (i);
2743 if (!_state_of_the_state & InCleanup) {
2745 /* save state so we don't end up with a session file
2746 referring to non-existent sources.
2749 save_state (_current_snapshot_name);
2752 SourceRemoved(source); /* EMIT SIGNAL */
2756 Session::source_by_id (const PBD::ID& id)
2758 Glib::Mutex::Lock lm (audio_source_lock);
2759 AudioSourceList::iterator i;
2762 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2766 /* XXX search MIDI or other searches here */
2772 Session::peak_path_from_audio_path (string audio_path)
2774 /* XXX hardly bombproof! fix me */
2778 res = Glib::path_get_dirname (audio_path);
2779 res = Glib::path_get_dirname (res);
2781 res += peak_dir_name;
2783 res += PBD::basename_nosuffix (audio_path);
2790 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2793 string old_basename = PBD::basename_nosuffix (oldname);
2794 string new_legalized = legalize_for_path (newname);
2796 /* note: we know (or assume) the old path is already valid */
2800 /* destructive file sources have a name of the form:
2802 /path/to/Tnnnn-NAME(%[LR])?.wav
2804 the task here is to replace NAME with the new name.
2807 /* find last slash */
2811 string::size_type slash;
2812 string::size_type dash;
2814 if ((slash = path.find_last_of ('/')) == string::npos) {
2818 dir = path.substr (0, slash+1);
2820 /* '-' is not a legal character for the NAME part of the path */
2822 if ((dash = path.find_last_of ('-')) == string::npos) {
2826 prefix = path.substr (slash+1, dash-(slash+1));
2831 path += new_legalized;
2832 path += ".wav"; /* XXX gag me with a spoon */
2836 /* non-destructive file sources have a name of the form:
2838 /path/to/NAME-nnnnn(%[LR])?.wav
2840 the task here is to replace NAME with the new name.
2845 string::size_type slash;
2846 string::size_type dash;
2847 string::size_type postfix;
2849 /* find last slash */
2851 if ((slash = path.find_last_of ('/')) == string::npos) {
2855 dir = path.substr (0, slash+1);
2857 /* '-' is not a legal character for the NAME part of the path */
2859 if ((dash = path.find_last_of ('-')) == string::npos) {
2863 suffix = path.substr (dash+1);
2865 // Suffix is now everything after the dash. Now we need to eliminate
2866 // the nnnnn part, which is done by either finding a '%' or a '.'
2868 postfix = suffix.find_last_of ("%");
2869 if (postfix == string::npos) {
2870 postfix = suffix.find_last_of ('.');
2873 if (postfix != string::npos) {
2874 suffix = suffix.substr (postfix);
2876 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2880 const uint32_t limit = 10000;
2881 char buf[PATH_MAX+1];
2883 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2885 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2887 if (access (buf, F_OK) != 0) {
2895 error << "FATAL ERROR! Could not find a " << endl;
2904 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2908 char buf[PATH_MAX+1];
2909 const uint32_t limit = 10000;
2913 legalized = legalize_for_path (name);
2915 /* find a "version" of the file name that doesn't exist in
2916 any of the possible directories.
2919 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2921 vector<space_and_path>::iterator i;
2922 uint32_t existing = 0;
2924 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2929 spath += tape_dir_name;
2931 spath += sound_dir_name;
2936 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2937 } else if (nchan == 2) {
2939 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2941 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2943 } else if (nchan < 26) {
2944 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2946 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2954 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2955 } else if (nchan == 2) {
2957 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2959 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2961 } else if (nchan < 26) {
2962 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2964 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2968 if (access (buf, F_OK) == 0) {
2973 if (existing == 0) {
2978 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2979 throw failed_constructor();
2983 /* we now have a unique name for the file, but figure out where to
2990 spath = tape_dir ();
2992 spath = discover_best_sound_dir ();
2995 string::size_type pos = foo.find_last_of ('/');
2997 if (pos == string::npos) {
3000 spath += foo.substr (pos + 1);
3007 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3009 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3011 /* this might throw failed_constructor(), which is OK */
3014 return new DestructiveFileSource (spath,
3015 Config->get_native_file_data_format(),
3016 Config->get_native_file_header_format(),
3019 return new SndFileSource (spath,
3020 Config->get_native_file_data_format(),
3021 Config->get_native_file_header_format(),
3026 /* Playlist management */
3029 Session::playlist_by_name (string name)
3031 Glib::Mutex::Lock lm (playlist_lock);
3032 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3033 if ((*i)->name() == name) {
3037 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3038 if ((*i)->name() == name) {
3046 Session::add_playlist (Playlist* playlist)
3048 if (playlist->hidden()) {
3053 Glib::Mutex::Lock lm (playlist_lock);
3054 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3055 playlists.insert (playlists.begin(), playlist);
3057 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3058 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3064 PlaylistAdded (playlist); /* EMIT SIGNAL */
3068 Session::track_playlist (Playlist* pl, bool inuse)
3070 PlaylistList::iterator x;
3073 Glib::Mutex::Lock lm (playlist_lock);
3076 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3078 unused_playlists.insert (pl);
3080 if ((x = playlists.find (pl)) != playlists.end()) {
3081 playlists.erase (x);
3086 //cerr << "shifting playlist to used: " << pl->name() << endl;
3088 playlists.insert (pl);
3090 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3091 unused_playlists.erase (x);
3098 Session::remove_playlist (Playlist* playlist)
3100 if (_state_of_the_state & Deletion) {
3105 Glib::Mutex::Lock lm (playlist_lock);
3106 // cerr << "removing playlist: " << playlist->name() << endl;
3108 PlaylistList::iterator i;
3110 i = find (playlists.begin(), playlists.end(), playlist);
3112 if (i != playlists.end()) {
3113 playlists.erase (i);
3116 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3117 if (i != unused_playlists.end()) {
3118 unused_playlists.erase (i);
3125 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3129 Session::set_audition (AudioRegion* r)
3131 pending_audition_region = r;
3132 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3133 schedule_butler_transport_work ();
3137 Session::non_realtime_set_audition ()
3139 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3140 auditioner->audition_current_playlist ();
3141 } else if (pending_audition_region) {
3142 auditioner->audition_region (*pending_audition_region);
3144 pending_audition_region = 0;
3145 AuditionActive (true); /* EMIT SIGNAL */
3149 Session::audition_playlist ()
3151 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3152 ev->set_ptr ((void*) 0xfeedface);
3157 Session::audition_region (Region& r)
3159 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3161 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3168 Session::cancel_audition ()
3170 if (auditioner->active()) {
3171 auditioner->cancel_audition ();
3172 AuditionActive (false); /* EMIT SIGNAL */
3177 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3179 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3183 Session::remove_empty_sounds ()
3186 PathScanner scanner;
3191 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3193 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3195 if (AudioFileSource::is_empty (*(*i))) {
3197 unlink ((*i)->c_str());
3199 string peak_path = peak_path_from_audio_path (**i);
3200 unlink (peak_path.c_str());
3206 delete possible_audiofiles;
3210 Session::is_auditioning () const
3212 /* can be called before we have an auditioner object */
3214 return auditioner->active();
3221 Session::set_all_solo (bool yn)
3223 shared_ptr<RouteList> r = routes.reader ();
3225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3226 if (!(*i)->hidden()) {
3227 (*i)->set_solo (yn, this);
3235 Session::set_all_mute (bool yn)
3237 shared_ptr<RouteList> r = routes.reader ();
3239 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3240 if (!(*i)->hidden()) {
3241 (*i)->set_mute (yn, this);
3249 Session::n_diskstreams () const
3253 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3255 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3256 if (!(*i)->hidden()) {
3264 Session::graph_reordered ()
3266 /* don't do this stuff if we are setting up connections
3267 from a set_state() call.
3270 if (_state_of_the_state & InitialConnecting) {
3276 /* force all diskstreams to update their capture offset values to
3277 reflect any changes in latencies within the graph.
3280 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3282 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3283 (*i)->set_capture_offset ();
3288 Session::record_disenable_all ()
3290 record_enable_change_all (false);
3294 Session::record_enable_all ()
3296 record_enable_change_all (true);
3300 Session::record_enable_change_all (bool yn)
3302 shared_ptr<RouteList> r = routes.reader ();
3304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3307 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3308 at->set_record_enable (yn, this);
3312 /* since we don't keep rec-enable state, don't mark session dirty */
3316 Session::add_redirect (Redirect* redirect)
3320 PortInsert* port_insert;
3321 PluginInsert* plugin_insert;
3323 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3324 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3325 _port_inserts.insert (_port_inserts.begin(), port_insert);
3326 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3327 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3329 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3332 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3333 _sends.insert (_sends.begin(), send);
3335 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3339 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3345 Session::remove_redirect (Redirect* redirect)
3349 PortInsert* port_insert;
3350 PluginInsert* plugin_insert;
3352 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3353 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3354 _port_inserts.remove (port_insert);
3355 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3356 _plugin_inserts.remove (plugin_insert);
3358 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3361 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3362 _sends.remove (send);
3364 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3372 Session::available_capture_duration ()
3374 const double scale = 4096.0 / sizeof (Sample);
3376 if (_total_free_4k_blocks * scale > (double) max_frames) {
3380 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3384 Session::add_connection (ARDOUR::Connection* connection)
3387 Glib::Mutex::Lock guard (connection_lock);
3388 _connections.push_back (connection);
3391 ConnectionAdded (connection); /* EMIT SIGNAL */
3397 Session::remove_connection (ARDOUR::Connection* connection)
3399 bool removed = false;
3402 Glib::Mutex::Lock guard (connection_lock);
3403 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3405 if (i != _connections.end()) {
3406 _connections.erase (i);
3412 ConnectionRemoved (connection); /* EMIT SIGNAL */
3418 ARDOUR::Connection *
3419 Session::connection_by_name (string name) const
3421 Glib::Mutex::Lock lm (connection_lock);
3423 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3424 if ((*i)->name() == name) {
3433 Session::set_edit_mode (EditMode mode)
3438 Glib::Mutex::Lock lm (playlist_lock);
3440 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3441 (*i)->set_edit_mode (mode);
3446 ControlChanged (EditingMode); /* EMIT SIGNAL */
3450 Session::tempo_map_changed (Change ignored)
3457 Session::ensure_passthru_buffers (uint32_t howmany)
3459 while (howmany > _passthru_buffers.size()) {
3461 #ifdef NO_POSIX_MEMALIGN
3462 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3464 posix_memalign((void **)&p,16,current_block_size * 4);
3466 _passthru_buffers.push_back (p);
3470 #ifdef NO_POSIX_MEMALIGN
3471 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3473 posix_memalign((void **)&p,16,current_block_size * 4);
3475 memset (p, 0, sizeof (Sample) * current_block_size);
3476 _silent_buffers.push_back (p);
3480 #ifdef NO_POSIX_MEMALIGN
3481 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3483 posix_memalign((void **)&p,16,current_block_size * 4);
3485 memset (p, 0, sizeof (Sample) * current_block_size);
3486 _send_buffers.push_back (p);
3489 allocate_pan_automation_buffers (current_block_size, howmany, false);
3493 Session::next_send_name ()
3496 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3501 Session::next_insert_name ()
3504 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3508 /* Named Selection management */
3511 Session::named_selection_by_name (string name)
3513 Glib::Mutex::Lock lm (named_selection_lock);
3514 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3515 if ((*i)->name == name) {
3523 Session::add_named_selection (NamedSelection* named_selection)
3526 Glib::Mutex::Lock lm (named_selection_lock);
3527 named_selections.insert (named_selections.begin(), named_selection);
3532 NamedSelectionAdded (); /* EMIT SIGNAL */
3536 Session::remove_named_selection (NamedSelection* named_selection)
3538 bool removed = false;
3541 Glib::Mutex::Lock lm (named_selection_lock);
3543 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3545 if (i != named_selections.end()) {
3547 named_selections.erase (i);
3554 NamedSelectionRemoved (); /* EMIT SIGNAL */
3559 Session::reset_native_file_format ()
3561 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3564 (*i)->reset_write_sources (false);
3569 Session::route_name_unique (string n) const
3571 shared_ptr<RouteList> r = routes.reader ();
3573 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3574 if ((*i)->name() == n) {
3583 Session::cleanup_audio_file_source (AudioFileSource& fs)
3585 return fs.move_to_trash (dead_sound_dir_name);
3589 Session::n_playlists () const
3591 Glib::Mutex::Lock lm (playlist_lock);
3592 return playlists.size();
3596 Session::set_solo_model (SoloModel sm)
3598 if (sm != _solo_model) {
3600 ControlChanged (SoloingModel);
3606 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3608 if (!force && howmany <= _npan_buffers) {
3612 if (_pan_automation_buffer) {
3614 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3615 delete [] _pan_automation_buffer[i];
3618 delete [] _pan_automation_buffer;
3621 _pan_automation_buffer = new pan_t*[howmany];
3623 for (uint32_t i = 0; i < howmany; ++i) {
3624 _pan_automation_buffer[i] = new pan_t[nframes];
3627 _npan_buffers = howmany;
3631 Session::freeze (InterThreadInfo& itt)
3633 shared_ptr<RouteList> r = routes.reader ();
3635 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3639 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3640 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3651 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3652 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3656 AudioFileSource* fsource;
3658 char buf[PATH_MAX+1];
3661 jack_nframes_t position;
3662 jack_nframes_t this_chunk;
3663 jack_nframes_t to_do;
3664 vector<Sample*> buffers;
3666 // any bigger than this seems to cause stack overflows in called functions
3667 const jack_nframes_t chunk_size = (128 * 1024)/4;
3669 g_atomic_int_set (&processing_prohibited, 1);
3671 /* call tree *MUST* hold route_lock */
3673 if ((playlist = track.diskstream()->playlist()) == 0) {
3677 /* external redirects will be a problem */
3679 if (track.has_external_redirects()) {
3683 nchans = track.audio_diskstream()->n_channels();
3685 dir = discover_best_sound_dir ();
3687 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3689 for (x = 0; x < 99999; ++x) {
3690 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3691 if (access (buf, F_OK) != 0) {
3697 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3702 fsource = new SndFileSource (buf,
3703 Config->get_native_file_data_format(),
3704 Config->get_native_file_header_format(),
3709 catch (failed_constructor& err) {
3710 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3714 srcs.push_back(fsource);
3717 /* XXX need to flush all redirects */
3722 /* create a set of reasonably-sized buffers */
3724 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3726 #ifdef NO_POSIX_MEMALIGN
3727 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3729 posix_memalign((void **)&b,16,chunk_size * 4);
3731 buffers.push_back (b);
3734 while (to_do && !itt.cancel) {
3736 this_chunk = min (to_do, chunk_size);
3738 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3743 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3744 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3747 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3753 start += this_chunk;
3754 to_do -= this_chunk;
3756 itt.progress = (float) (1.0 - ((double) to_do / len));
3765 xnow = localtime (&now);
3767 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3768 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3770 afs->update_header (position, *xnow, now);
3774 /* build peakfile for new source */
3776 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3777 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3779 afs->build_peaks ();
3788 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3789 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3791 afs->mark_for_remove ();
3797 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3801 g_atomic_int_set (&processing_prohibited, 0);
3809 Session::get_silent_buffers (uint32_t howmany)
3811 for (uint32_t i = 0; i < howmany; ++i) {
3812 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3814 return _silent_buffers;
3818 Session::ntracks () const
3821 shared_ptr<RouteList> r = routes.reader ();
3823 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3824 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3833 Session::nbusses () const
3836 shared_ptr<RouteList> r = routes.reader ();
3838 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3839 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3848 Session::set_layer_model (LayerModel lm)
3850 if (lm != layer_model) {
3853 ControlChanged (LayeringModel);
3858 Session::set_xfade_model (CrossfadeModel xm)
3860 if (xm != xfade_model) {
3863 ControlChanged (CrossfadingModel);
3868 Session::add_curve(Curve *curve)
3870 curves[curve->id()] = curve;
3874 Session::add_automation_list(AutomationList *al)
3876 automation_lists[al->id()] = al;