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>
74 #include <ardour/source_factory.h>
77 #include <ardour/osc.h>
83 using namespace ARDOUR;
85 using boost::shared_ptr;
87 const char* Session::_template_suffix = X_(".template");
88 const char* Session::_statefile_suffix = X_(".ardour");
89 const char* Session::_pending_suffix = X_(".pending");
90 const char* Session::sound_dir_name = X_("sounds");
91 const char* Session::tape_dir_name = X_("tapes");
92 const char* Session::peak_dir_name = X_("peaks");
93 const char* Session::dead_sound_dir_name = X_("dead_sounds");
95 Session::compute_peak_t Session::compute_peak = 0;
96 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
97 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
98 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
100 sigc::signal<int> Session::AskAboutPendingState;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::SMPTETypeChanged;
105 sigc::signal<void> Session::PullupChanged;
106 sigc::signal<void> Session::StartTimeChanged;
107 sigc::signal<void> Session::EndTimeChanged;
110 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
113 char buf[PATH_MAX+1];
117 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
118 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
124 /* check to see if it exists, and what it is */
126 if (stat (str.c_str(), &statbuf)) {
127 if (errno == ENOENT) {
130 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
138 /* it exists, so it must either be the name
139 of the directory, or the name of the statefile
143 if (S_ISDIR (statbuf.st_mode)) {
145 string::size_type slash = str.find_last_of ('/');
147 if (slash == string::npos) {
149 /* a subdirectory of cwd, so statefile should be ... */
155 tmp += _statefile_suffix;
159 if (stat (tmp.c_str(), &statbuf)) {
160 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
170 /* some directory someplace in the filesystem.
171 the snapshot name is the directory name
176 snapshot = str.substr (slash+1);
180 } else if (S_ISREG (statbuf.st_mode)) {
182 string::size_type slash = str.find_last_of ('/');
183 string::size_type suffix;
185 /* remove the suffix */
187 if (slash != string::npos) {
188 snapshot = str.substr (slash+1);
193 suffix = snapshot.find (_statefile_suffix);
195 if (suffix == string::npos) {
196 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
202 snapshot = snapshot.substr (0, suffix);
204 if (slash == string::npos) {
206 /* we must be in the directory where the
207 statefile lives. get it using cwd().
210 char cwd[PATH_MAX+1];
212 if (getcwd (cwd, sizeof (cwd)) == 0) {
213 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
222 /* full path to the statefile */
224 path = str.substr (0, slash);
229 /* what type of file is it? */
230 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
236 /* its the name of a new directory. get the name
240 string::size_type slash = str.find_last_of ('/');
242 if (slash == string::npos) {
244 /* no slash, just use the name, but clean it up */
246 path = legalize_for_path (str);
252 snapshot = str.substr (slash+1);
259 Session::Session (AudioEngine &eng,
261 string snapshot_name,
262 string* mix_template)
265 _scratch_buffers(new BufferSet()),
266 _silent_buffers(new BufferSet()),
267 _send_buffers(new BufferSet()),
268 _mmc_port (default_mmc_port),
269 _mtc_port (default_mtc_port),
270 _midi_port (default_midi_port),
271 pending_events (2048),
272 //midi_requests (128), // the size of this should match the midi request pool size
273 _send_smpte_update (false),
274 diskstreams (new DiskstreamList),
275 routes (new RouteList),
276 auditioner ((Auditioner*) 0),
282 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
284 n_physical_outputs = _engine.n_physical_outputs();
285 n_physical_inputs = _engine.n_physical_inputs();
287 first_stage_init (fullpath, snapshot_name);
289 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
290 cerr << "create failed\n";
291 throw failed_constructor ();
294 if (second_stage_init (new_session)) {
295 cerr << "2nd state failed\n";
296 throw failed_constructor ();
299 store_recent_sessions(_name, _path);
301 bool was_dirty = dirty();
303 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
305 Config->ParameterChanged.connect (mem_fun (*this, &Session::handle_configuration_change));
308 DirtyChanged (); /* EMIT SIGNAL */
312 Session::Session (AudioEngine &eng,
314 string snapshot_name,
315 AutoConnectOption input_ac,
316 AutoConnectOption output_ac,
317 uint32_t control_out_channels,
318 uint32_t master_out_channels,
319 uint32_t requested_physical_in,
320 uint32_t requested_physical_out,
321 jack_nframes_t initial_length)
324 _scratch_buffers(new BufferSet()),
325 _silent_buffers(new BufferSet()),
326 _send_buffers(new BufferSet()),
327 _mmc_port (default_mmc_port),
328 _mtc_port (default_mtc_port),
329 _midi_port (default_midi_port),
330 pending_events (2048),
331 //midi_requests (16),
332 _send_smpte_update (false),
333 diskstreams (new DiskstreamList),
334 routes (new RouteList),
340 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
342 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
343 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
345 first_stage_init (fullpath, snapshot_name);
347 if (create (new_session, 0, initial_length)) {
348 throw failed_constructor ();
351 if (control_out_channels) {
352 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
359 if (master_out_channels) {
360 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
366 /* prohibit auto-connect to master, because there isn't one */
367 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
370 input_auto_connect = input_ac;
371 output_auto_connect = output_ac;
373 if (second_stage_init (new_session)) {
374 throw failed_constructor ();
377 store_recent_sessions(_name, _path);
379 bool was_dirty = dirty ();
381 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
384 DirtyChanged (); /* EMIT SIGNAL */
390 /* if we got to here, leaving pending capture state around
394 remove_pending_capture_state ();
396 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
397 _engine.remove_session ();
399 GoingAway (); /* EMIT SIGNAL */
405 /* clear history so that no references to objects are held any more */
409 /* clear state tree so that no references to objects are held any more */
415 terminate_butler_thread ();
416 //terminate_midi_thread ();
418 if (click_data && click_data != default_click) {
419 delete [] click_data;
422 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
423 delete [] click_emphasis_data;
428 delete _scratch_buffers;
429 delete _silent_buffers;
430 delete _send_buffers;
432 AudioDiskstream::free_working_buffers();
434 #undef TRACK_DESTRUCTION
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete named selections\n";
437 #endif /* TRACK_DESTRUCTION */
438 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
439 NamedSelectionList::iterator tmp;
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete playlists\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
452 PlaylistList::iterator tmp;
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete regions\n";
464 #endif /* TRACK_DESTRUCTION */
466 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
467 i->second->drop_references ();
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete routes\n";
474 #endif /* TRACK_DESTRUCTION */
476 RCUWriter<RouteList> writer (routes);
477 boost::shared_ptr<RouteList> r = writer.get_copy ();
478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
479 (*i)->drop_references ();
482 /* writer goes out of scope and updates master */
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete diskstreams\n";
489 #endif /* TRACK_DESTRUCTION */
491 RCUWriter<DiskstreamList> dwriter (diskstreams);
492 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
493 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
494 (*i)->drop_references ();
498 diskstreams.flush ();
500 #ifdef TRACK_DESTRUCTION
501 cerr << "delete audio sources\n";
502 #endif /* TRACK_DESTRUCTION */
503 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
504 SourceMap::iterator tmp;
509 i->second->drop_references ();
516 #ifdef TRACK_DESTRUCTION
517 cerr << "delete mix groups\n";
518 #endif /* TRACK_DESTRUCTION */
519 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
520 list<RouteGroup*>::iterator tmp;
530 #ifdef TRACK_DESTRUCTION
531 cerr << "delete edit groups\n";
532 #endif /* TRACK_DESTRUCTION */
533 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
534 list<RouteGroup*>::iterator tmp;
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete connections\n";
546 #endif /* TRACK_DESTRUCTION */
547 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
548 ConnectionList::iterator tmp;
558 if (butler_mixdown_buffer) {
559 delete [] butler_mixdown_buffer;
562 if (butler_gain_buffer) {
563 delete [] butler_gain_buffer;
566 Crossfade::set_buffer_size (0);
574 Session::set_worst_io_latencies ()
576 _worst_output_latency = 0;
577 _worst_input_latency = 0;
579 if (!_engine.connected()) {
583 boost::shared_ptr<RouteList> r = routes.reader ();
585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
586 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
587 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
592 Session::when_engine_running ()
594 string first_physical_output;
596 /* we don't want to run execute this again */
598 first_time_running.disconnect ();
600 set_block_size (_engine.frames_per_cycle());
601 set_frame_rate (_engine.frame_rate());
603 /* every time we reconnect, recompute worst case output latencies */
605 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
607 if (synced_to_jack()) {
608 _engine.transport_stop ();
611 if (Config->get_jack_time_master()) {
612 _engine.transport_locate (_transport_frame);
620 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
622 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
624 /* existing state for Click */
626 if (_click_io->set_state (*child->children().front()) == 0) {
628 _clicking = click_requested;
632 error << _("could not setup Click I/O") << endmsg;
638 /* default state for Click */
640 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
642 if (first_physical_output.length()) {
643 if (_click_io->add_output_port (first_physical_output, this)) {
644 // relax, even though its an error
646 _clicking = click_requested;
652 catch (failed_constructor& err) {
653 error << _("cannot setup Click I/O") << endmsg;
656 set_worst_io_latencies ();
659 ControlChanged (Clicking); /* EMIT SIGNAL */
662 if (auditioner == 0) {
664 /* we delay creating the auditioner till now because
665 it makes its own connections to ports named
666 in the ARDOUR_RC config file. the engine has
667 to be running for this to work.
671 auditioner.reset (new Auditioner (*this));
674 catch (failed_constructor& err) {
675 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
679 /* Create a set of Connection objects that map
680 to the physical outputs currently available
685 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
687 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
689 Connection* c = new OutputConnection (buf, true);
692 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
697 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
699 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
701 Connection* c = new InputConnection (buf, true);
704 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
711 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
713 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
715 Connection* c = new OutputConnection (buf, true);
719 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
720 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
725 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
727 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
729 Connection* c = new InputConnection (buf, true);
733 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
734 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
743 /* create master/control ports */
748 /* force the master to ignore any later call to this */
750 if (_master_out->pending_state_node) {
751 _master_out->ports_became_legal();
754 /* no panner resets till we are through */
756 _master_out->defer_pan_reset ();
758 while (_master_out->n_inputs().get(DataType::AUDIO)
759 < _master_out->input_maximum().get(DataType::AUDIO)) {
760 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
761 error << _("cannot setup master inputs")
767 while (_master_out->n_outputs().get(DataType::AUDIO)
768 < _master_out->output_maximum().get(DataType::AUDIO)) {
769 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
770 error << _("cannot setup master outputs")
777 _master_out->allow_pan_reset ();
781 Connection* c = new OutputConnection (_("Master Out"), true);
783 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
785 c->add_connection ((int) n, _master_out->input(n)->name());
792 /* catch up on send+insert cnts */
796 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
799 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
800 if (id > insert_cnt) {
808 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
811 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
818 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
820 /* hook us up to the engine */
822 _engine.set_session (this);
827 osc->set_session (*this);
830 _state_of_the_state = Clean;
832 DirtyChanged (); /* EMIT SIGNAL */
836 Session::hookup_io ()
838 /* stop graph reordering notifications from
839 causing resorts, etc.
842 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
844 /* Tell all IO objects to create their ports */
851 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
852 if (_control_out->add_input_port ("", this)) {
853 error << _("cannot setup control inputs")
859 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
860 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
861 error << _("cannot set up master outputs")
869 /* Tell all IO objects to connect themselves together */
871 IO::enable_connecting ();
873 /* Now reset all panners */
875 IO::reset_panners ();
877 /* Anyone who cares about input state, wake up and do something */
879 IOConnectionsComplete (); /* EMIT SIGNAL */
881 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
883 /* now handle the whole enchilada as if it was one
889 /* update mixer solo state */
895 Session::playlist_length_changed (Playlist* pl)
897 /* we can't just increase end_location->end() if pl->get_maximum_extent()
898 if larger. if the playlist used to be the longest playlist,
899 and its now shorter, we have to decrease end_location->end(). hence,
900 we have to iterate over all diskstreams and check the
901 playlists currently in use.
907 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
911 if ((playlist = dstream->playlist()) != 0) {
912 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
915 /* see comment in playlist_length_changed () */
920 Session::record_enabling_legal () const
922 /* this used to be in here, but survey says.... we don't need to restrict it */
923 // if (record_status() == Recording) {
934 Session::set_auto_play (bool yn)
936 if (auto_play != yn) {
939 ControlChanged (AutoPlay);
944 Session::set_auto_return (bool yn)
946 if (auto_return != yn) {
949 ControlChanged (AutoReturn);
954 Session::set_crossfades_active (bool yn)
956 if (crossfades_active != yn) {
957 crossfades_active = yn;
959 ControlChanged (CrossFadesActive);
964 Session::set_do_not_record_plugins (bool yn)
966 if (do_not_record_plugins != yn) {
967 do_not_record_plugins = yn;
969 ControlChanged (RecordingPlugins);
974 Session::set_auto_input (bool yn)
976 if (auto_input != yn) {
979 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
980 /* auto-input only makes a difference if we're rolling */
982 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
984 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
985 if ((*i)->record_enabled ()) {
986 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
987 (*i)->monitor_input (!auto_input);
993 ControlChanged (AutoInput);
998 Session::reset_input_monitor_state ()
1000 if (transport_rolling()) {
1002 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1004 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1005 if ((*i)->record_enabled ()) {
1006 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1007 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
1011 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1013 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1014 if ((*i)->record_enabled ()) {
1015 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1016 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1024 Session::set_input_auto_connect (bool yn)
1027 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1029 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1035 Session::get_input_auto_connect () const
1037 return (input_auto_connect & AutoConnectPhysical);
1041 Session::set_output_auto_connect (AutoConnectOption aco)
1043 output_auto_connect = aco;
1048 Session::auto_punch_start_changed (Location* location)
1050 replace_event (Event::PunchIn, location->start());
1052 if (get_record_enabled() && get_punch_in()) {
1053 /* capture start has been changed, so save new pending state */
1054 save_state ("", true);
1059 Session::auto_punch_end_changed (Location* location)
1061 jack_nframes_t when_to_stop = location->end();
1062 // when_to_stop += _worst_output_latency + _worst_input_latency;
1063 replace_event (Event::PunchOut, when_to_stop);
1067 Session::auto_punch_changed (Location* location)
1069 jack_nframes_t when_to_stop = location->end();
1071 replace_event (Event::PunchIn, location->start());
1072 //when_to_stop += _worst_output_latency + _worst_input_latency;
1073 replace_event (Event::PunchOut, when_to_stop);
1077 Session::auto_loop_changed (Location* location)
1079 replace_event (Event::AutoLoop, location->end(), location->start());
1081 if (transport_rolling() && get_auto_loop()) {
1083 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1085 if (_transport_frame > location->end()) {
1086 // relocate to beginning of loop
1087 clear_events (Event::LocateRoll);
1089 request_locate (location->start(), true);
1092 else if (seamless_loop && !loop_changing) {
1094 // schedule a locate-roll to refill the diskstreams at the
1095 // previous loop end
1096 loop_changing = true;
1098 if (location->end() > last_loopend) {
1099 clear_events (Event::LocateRoll);
1100 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1107 last_loopend = location->end();
1112 Session::set_auto_punch_location (Location* location)
1116 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1117 auto_punch_start_changed_connection.disconnect();
1118 auto_punch_end_changed_connection.disconnect();
1119 auto_punch_changed_connection.disconnect();
1120 existing->set_auto_punch (false, this);
1121 remove_event (existing->start(), Event::PunchIn);
1122 clear_events (Event::PunchOut);
1123 auto_punch_location_changed (0);
1128 if (location == 0) {
1132 if (location->end() <= location->start()) {
1133 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1137 auto_punch_start_changed_connection.disconnect();
1138 auto_punch_end_changed_connection.disconnect();
1139 auto_punch_changed_connection.disconnect();
1141 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1142 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1143 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1145 location->set_auto_punch (true, this);
1146 auto_punch_location_changed (location);
1150 Session::set_punch_in (bool yn)
1152 if (punch_in == yn) {
1158 if ((location = _locations.auto_punch_location()) != 0) {
1159 if ((punch_in = yn) == true) {
1160 replace_event (Event::PunchIn, location->start());
1162 remove_event (location->start(), Event::PunchIn);
1167 ControlChanged (PunchIn); /* EMIT SIGNAL */
1171 Session::set_punch_out (bool yn)
1173 if (punch_out == yn) {
1179 if ((location = _locations.auto_punch_location()) != 0) {
1180 if ((punch_out = yn) == true) {
1181 replace_event (Event::PunchOut, location->end());
1183 clear_events (Event::PunchOut);
1188 ControlChanged (PunchOut); /* EMIT SIGNAL */
1192 Session::set_auto_loop_location (Location* location)
1196 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1197 auto_loop_start_changed_connection.disconnect();
1198 auto_loop_end_changed_connection.disconnect();
1199 auto_loop_changed_connection.disconnect();
1200 existing->set_auto_loop (false, this);
1201 remove_event (existing->end(), Event::AutoLoop);
1202 auto_loop_location_changed (0);
1207 if (location == 0) {
1211 if (location->end() <= location->start()) {
1212 error << _("Session: you can't use a mark for auto loop") << endmsg;
1216 last_loopend = location->end();
1218 auto_loop_start_changed_connection.disconnect();
1219 auto_loop_end_changed_connection.disconnect();
1220 auto_loop_changed_connection.disconnect();
1222 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1223 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1224 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1226 location->set_auto_loop (true, this);
1227 auto_loop_location_changed (location);
1231 Session::locations_added (Location* ignored)
1237 Session::locations_changed ()
1239 _locations.apply (*this, &Session::handle_locations_changed);
1243 Session::handle_locations_changed (Locations::LocationList& locations)
1245 Locations::LocationList::iterator i;
1247 bool set_loop = false;
1248 bool set_punch = false;
1250 for (i = locations.begin(); i != locations.end(); ++i) {
1254 if (location->is_auto_punch()) {
1255 set_auto_punch_location (location);
1258 if (location->is_auto_loop()) {
1259 set_auto_loop_location (location);
1266 set_auto_loop_location (0);
1269 set_auto_punch_location (0);
1276 Session::enable_record ()
1278 /* XXX really atomic compare+swap here */
1279 if (g_atomic_int_get (&_record_status) != Recording) {
1280 g_atomic_int_set (&_record_status, Recording);
1281 _last_record_location = _transport_frame;
1282 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1284 if (Config->get_use_hardware_monitoring() && auto_input) {
1285 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1286 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1287 if ((*i)->record_enabled ()) {
1288 (*i)->monitor_input (true);
1293 RecordStateChanged ();
1298 Session::disable_record (bool rt_context, bool force)
1302 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1304 if (!Config->get_latched_record_enable () || force) {
1305 g_atomic_int_set (&_record_status, Disabled);
1307 if (rs == Recording) {
1308 g_atomic_int_set (&_record_status, Enabled);
1312 // FIXME: timestamp correct? [DR]
1313 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1314 // does this /need/ to be sent in all cases?
1316 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1318 if (Config->get_use_hardware_monitoring() && auto_input) {
1319 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1321 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1322 if ((*i)->record_enabled ()) {
1323 (*i)->monitor_input (false);
1328 RecordStateChanged (); /* emit signal */
1331 remove_pending_capture_state ();
1337 Session::step_back_from_record ()
1339 g_atomic_int_set (&_record_status, Enabled);
1341 if (Config->get_use_hardware_monitoring()) {
1342 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1344 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1345 if (auto_input && (*i)->record_enabled ()) {
1346 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1347 (*i)->monitor_input (false);
1354 Session::maybe_enable_record ()
1356 g_atomic_int_set (&_record_status, Enabled);
1358 /* XXX this save should really happen in another thread. its needed so that
1359 pending capture state can be recovered if we crash.
1362 save_state ("", true);
1364 if (_transport_speed) {
1369 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1370 RecordStateChanged (); /* EMIT SIGNAL */
1377 Session::audible_frame () const
1380 jack_nframes_t offset;
1383 /* the first of these two possible settings for "offset"
1384 mean that the audible frame is stationary until
1385 audio emerges from the latency compensation
1388 the second means that the audible frame is stationary
1389 until audio would emerge from a physical port
1390 in the absence of any plugin latency compensation
1393 offset = _worst_output_latency;
1395 if (offset > current_block_size) {
1396 offset -= current_block_size;
1398 /* XXX is this correct? if we have no external
1399 physical connections and everything is internal
1400 then surely this is zero? still, how
1401 likely is that anyway?
1403 offset = current_block_size;
1406 if (synced_to_jack()) {
1407 tf = _engine.transport_frame();
1409 tf = _transport_frame;
1412 if (_transport_speed == 0) {
1422 if (!non_realtime_work_pending()) {
1426 /* take latency into account */
1435 Session::set_frame_rate (jack_nframes_t frames_per_second)
1437 /** \fn void Session::set_frame_size(jack_nframes_t)
1438 the AudioEngine object that calls this guarantees
1439 that it will not be called while we are also in
1440 ::process(). Its fine to do things that block
1444 _base_frame_rate = frames_per_second;
1448 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1450 // XXX we need some equivalent to this, somehow
1451 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1455 /* XXX need to reset/reinstantiate all LADSPA plugins */
1459 Session::set_block_size (jack_nframes_t nframes)
1461 /* the AudioEngine guarantees
1462 that it will not be called while we are also in
1463 ::process(). It is therefore fine to do things that block
1469 current_block_size = nframes;
1471 ensure_buffers(_scratch_buffers->available());
1473 if (_gain_automation_buffer) {
1474 delete [] _gain_automation_buffer;
1476 _gain_automation_buffer = new gain_t[nframes];
1478 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1480 boost::shared_ptr<RouteList> r = routes.reader ();
1482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1483 (*i)->set_block_size (nframes);
1486 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1487 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1488 (*i)->set_block_size (nframes);
1491 set_worst_io_latencies ();
1496 Session::set_default_fade (float steepness, float fade_msecs)
1499 jack_nframes_t fade_frames;
1501 /* Don't allow fade of less 1 frame */
1503 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1510 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1514 default_fade_msecs = fade_msecs;
1515 default_fade_steepness = steepness;
1518 // jlc, WTF is this!
1519 Glib::RWLock::ReaderLock lm (route_lock);
1520 AudioRegion::set_default_fade (steepness, fade_frames);
1525 /* XXX have to do this at some point */
1526 /* foreach region using default fade, reset, then
1527 refill_all_diskstream_buffers ();
1532 struct RouteSorter {
1533 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1534 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1536 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1539 if (r1->fed_by.empty()) {
1540 if (r2->fed_by.empty()) {
1541 /* no ardour-based connections inbound to either route. just use signal order */
1542 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1544 /* r2 has connections, r1 does not; run r1 early */
1548 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1555 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1557 shared_ptr<Route> r2;
1559 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1560 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1564 /* make a copy of the existing list of routes that feed r1 */
1566 set<shared_ptr<Route> > existing = r1->fed_by;
1568 /* for each route that feeds r1, recurse, marking it as feeding
1572 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1575 /* r2 is a route that feeds r1 which somehow feeds base. mark
1576 base as being fed by r2
1579 rbase->fed_by.insert (r2);
1583 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1587 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1591 /* now recurse, so that we can mark base as being fed by
1592 all routes that feed r2
1595 trace_terminal (r2, rbase);
1602 Session::resort_routes ()
1604 /* don't do anything here with signals emitted
1605 by Routes while we are being destroyed.
1608 if (_state_of_the_state & Deletion) {
1615 RCUWriter<RouteList> writer (routes);
1616 shared_ptr<RouteList> r = writer.get_copy ();
1617 resort_routes_using (r);
1618 /* writer goes out of scope and forces update */
1623 Session::resort_routes_using (shared_ptr<RouteList> r)
1625 RouteList::iterator i, j;
1627 for (i = r->begin(); i != r->end(); ++i) {
1629 (*i)->fed_by.clear ();
1631 for (j = r->begin(); j != r->end(); ++j) {
1633 /* although routes can feed themselves, it will
1634 cause an endless recursive descent if we
1635 detect it. so don't bother checking for
1643 if ((*j)->feeds (*i)) {
1644 (*i)->fed_by.insert (*j);
1649 for (i = r->begin(); i != r->end(); ++i) {
1650 trace_terminal (*i, *i);
1657 cerr << "finished route resort\n";
1659 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1660 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1667 list<boost::shared_ptr<MidiTrack> >
1668 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1670 char track_name[32];
1671 uint32_t track_id = 0;
1673 uint32_t channels_used = 0;
1675 RouteList new_routes;
1676 list<boost::shared_ptr<MidiTrack> > ret;
1678 /* count existing midi tracks */
1681 shared_ptr<RouteList> r = routes.reader ();
1683 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1684 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1685 if (!(*i)->hidden()) {
1687 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1695 /* check for duplicate route names, since we might have pre-existing
1696 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1697 save, close,restart,add new route - first named route is now
1705 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1707 if (route_by_name (track_name) == 0) {
1711 } while (track_id < (UINT_MAX-1));
1714 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1716 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1717 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1720 channels_used += track->n_inputs ().get(DataType::MIDI);
1722 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1723 track->set_remote_control_id (ntracks());
1725 new_routes.push_back (track);
1726 ret.push_back (track);
1729 catch (failed_constructor &err) {
1730 error << _("Session: could not create new midi track.") << endmsg;
1731 // XXX should we delete the tracks already created?
1739 if (!new_routes.empty()) {
1740 add_routes (new_routes, false);
1741 save_state (_current_snapshot_name);
1747 list<boost::shared_ptr<AudioTrack> >
1748 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1750 char track_name[32];
1751 uint32_t track_id = 0;
1753 uint32_t channels_used = 0;
1755 RouteList new_routes;
1756 list<boost::shared_ptr<AudioTrack> > ret;
1758 /* count existing audio tracks */
1761 shared_ptr<RouteList> r = routes.reader ();
1763 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1764 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1765 if (!(*i)->hidden()) {
1767 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1773 vector<string> physinputs;
1774 vector<string> physoutputs;
1775 uint32_t nphysical_in;
1776 uint32_t nphysical_out;
1778 _engine.get_physical_outputs (physoutputs);
1779 _engine.get_physical_inputs (physinputs);
1783 /* check for duplicate route names, since we might have pre-existing
1784 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1785 save, close,restart,add new route - first named route is now
1793 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1795 if (route_by_name (track_name) == 0) {
1799 } while (track_id < (UINT_MAX-1));
1801 if (input_auto_connect & AutoConnectPhysical) {
1802 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1807 if (output_auto_connect & AutoConnectPhysical) {
1808 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1814 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1816 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1817 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1818 input_channels, output_channels)
1823 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1827 if (input_auto_connect & AutoConnectPhysical) {
1828 port = physinputs[(channels_used+x)%nphysical_in];
1831 if (port.length() && track->connect_input (track->input (x), port, this)) {
1837 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1841 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1842 port = physoutputs[(channels_used+x)%nphysical_out];
1843 } else if (output_auto_connect & AutoConnectMaster) {
1845 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1849 if (port.length() && track->connect_output (track->output (x), port, this)) {
1854 channels_used += track->n_inputs ().get(DataType::AUDIO);
1857 vector<string> cports;
1858 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1860 for (n = 0; n < ni; ++n) {
1861 cports.push_back (_control_out->input(n)->name());
1864 track->set_control_outs (cports);
1867 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1868 track->set_remote_control_id (ntracks());
1870 new_routes.push_back (track);
1871 ret.push_back (track);
1874 catch (failed_constructor &err) {
1875 error << _("Session: could not create new audio track.") << endmsg;
1876 // XXX should we delete the tracks already created?
1884 if (!new_routes.empty()) {
1885 add_routes (new_routes, false);
1886 save_state (_current_snapshot_name);
1893 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1896 uint32_t bus_id = 1;
1901 /* count existing audio busses */
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()) {
1915 vector<string> physinputs;
1916 vector<string> physoutputs;
1918 _engine.get_physical_outputs (physoutputs);
1919 _engine.get_physical_inputs (physinputs);
1926 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1928 if (route_by_name (bus_name) == 0) {
1932 } while (bus_id < (UINT_MAX-1));
1935 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1937 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1938 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1939 input_channels, output_channels)
1943 for (uint32_t x = 0; x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1947 if (input_auto_connect & AutoConnectPhysical) {
1948 port = physinputs[((n+x)%n_physical_inputs)];
1951 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1956 for (uint32_t x = 0; x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1960 if (output_auto_connect & AutoConnectPhysical) {
1961 port = physoutputs[((n+x)%n_physical_outputs)];
1962 } else if (output_auto_connect & AutoConnectMaster) {
1964 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1968 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1974 vector<string> cports;
1975 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1977 for (uint32_t n = 0; n < ni; ++n) {
1978 cports.push_back (_control_out->input(n)->name());
1980 bus->set_control_outs (cports);
1983 ret.push_back (bus);
1987 catch (failed_constructor &err) {
1988 error << _("Session: could not create new audio route.") << endmsg;
1997 add_routes (ret, false);
1998 save_state (_current_snapshot_name);
2006 Session::add_routes (RouteList& new_routes, bool save)
2009 RCUWriter<RouteList> writer (routes);
2010 shared_ptr<RouteList> r = writer.get_copy ();
2011 r->insert (r->end(), new_routes.begin(), new_routes.end());
2012 resort_routes_using (r);
2015 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2016 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
2017 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2018 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2019 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2021 if ((*x)->master()) {
2025 if ((*x)->control()) {
2026 _control_out = (*x);
2033 save_state (_current_snapshot_name);
2036 RouteAdded (new_routes); /* EMIT SIGNAL */
2040 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2042 /* need to do this in case we're rolling at the time, to prevent false underruns */
2043 dstream->do_refill_with_alloc();
2046 RCUWriter<DiskstreamList> writer (diskstreams);
2047 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2048 ds->push_back (dstream);
2051 dstream->set_block_size (current_block_size);
2053 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2054 /* this will connect to future changes, and check the current length */
2055 diskstream_playlist_changed (dstream);
2057 dstream->prepare ();
2061 Session::remove_route (shared_ptr<Route> route)
2064 RCUWriter<RouteList> writer (routes);
2065 shared_ptr<RouteList> rs = writer.get_copy ();
2068 /* deleting the master out seems like a dumb
2069 idea, but its more of a UI policy issue
2073 if (route == _master_out) {
2074 _master_out = shared_ptr<Route> ((Route*) 0);
2077 if (route == _control_out) {
2078 _control_out = shared_ptr<Route> ((Route*) 0);
2080 /* cancel control outs for all routes */
2082 vector<string> empty;
2084 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2085 (*r)->set_control_outs (empty);
2089 update_route_solo_state ();
2091 /* writer goes out of scope, forces route list update */
2095 boost::shared_ptr<Diskstream> ds;
2097 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2098 ds = t->diskstream();
2104 RCUWriter<DiskstreamList> dsl (diskstreams);
2105 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2110 find_current_end ();
2112 update_latency_compensation (false, false);
2115 /* XXX should we disconnect from the Route's signals ? */
2117 save_state (_current_snapshot_name);
2119 /* try to cause everyone to drop their references */
2121 route->drop_references ();
2125 Session::route_mute_changed (void* src)
2131 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2133 if (solo_update_disabled) {
2140 is_track = (dynamic_cast<Track*>(route.get()) != 0);
2142 shared_ptr<RouteList> r = routes.reader ();
2144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2146 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2150 /* don't mess with busses */
2152 if (dynamic_cast<Track*>((*i).get()) == 0) {
2158 /* don't mess with tracks */
2160 if (dynamic_cast<Track*>((*i).get()) != 0) {
2165 if ((*i) != route &&
2166 ((*i)->mix_group () == 0 ||
2167 (*i)->mix_group () != route->mix_group () ||
2168 !route->mix_group ()->is_active())) {
2170 if ((*i)->soloed()) {
2172 /* if its already soloed, and solo latching is enabled,
2173 then leave it as it is.
2176 if (_solo_latched) {
2183 solo_update_disabled = true;
2184 (*i)->set_solo (false, src);
2185 solo_update_disabled = false;
2189 bool something_soloed = false;
2190 bool same_thing_soloed = false;
2191 bool signal = false;
2193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2194 if ((*i)->soloed()) {
2195 something_soloed = true;
2196 if (dynamic_cast<Track*>((*i).get())) {
2198 same_thing_soloed = true;
2203 same_thing_soloed = true;
2211 if (something_soloed != currently_soloing) {
2213 currently_soloing = something_soloed;
2216 modify_solo_mute (is_track, same_thing_soloed);
2219 SoloActive (currently_soloing);
2226 Session::set_solo_latched (bool yn)
2228 if (yn != _solo_latched) {
2231 ControlChanged (SoloLatch);
2236 Session::update_route_solo_state ()
2239 bool is_track = false;
2240 bool signal = false;
2242 /* caller must hold RouteLock */
2244 /* this is where we actually implement solo by changing
2245 the solo mute setting of each track.
2248 shared_ptr<RouteList> r = routes.reader ();
2250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2251 if ((*i)->soloed()) {
2253 if (dynamic_cast<Track*>((*i).get())) {
2260 if (mute != currently_soloing) {
2262 currently_soloing = mute;
2265 if (!is_track && !mute) {
2267 /* nothing is soloed */
2269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2270 (*i)->set_solo_mute (false);
2280 modify_solo_mute (is_track, mute);
2283 SoloActive (currently_soloing);
2288 Session::modify_solo_mute (bool is_track, bool mute)
2290 shared_ptr<RouteList> r = routes.reader ();
2292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2296 /* only alter track solo mute */
2298 if (dynamic_cast<Track*>((*i).get())) {
2299 if ((*i)->soloed()) {
2300 (*i)->set_solo_mute (!mute);
2302 (*i)->set_solo_mute (mute);
2308 /* only alter bus solo mute */
2310 if (!dynamic_cast<Track*>((*i).get())) {
2312 if ((*i)->soloed()) {
2314 (*i)->set_solo_mute (false);
2318 /* don't mute master or control outs
2319 in response to another bus solo
2322 if ((*i) != _master_out &&
2323 (*i) != _control_out) {
2324 (*i)->set_solo_mute (mute);
2335 Session::catch_up_on_solo ()
2337 /* this is called after set_state() to catch the full solo
2338 state, which can't be correctly determined on a per-route
2339 basis, but needs the global overview that only the session
2342 update_route_solo_state();
2346 Session::route_by_name (string name)
2348 shared_ptr<RouteList> r = routes.reader ();
2350 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2351 if ((*i)->name() == name) {
2356 return shared_ptr<Route> ((Route*) 0);
2360 Session::route_by_id (PBD::ID id)
2362 shared_ptr<RouteList> r = routes.reader ();
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 if ((*i)->id() == id) {
2370 return shared_ptr<Route> ((Route*) 0);
2374 Session::route_by_remote_id (uint32_t id)
2376 shared_ptr<RouteList> r = routes.reader ();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if ((*i)->remote_control_id() == id) {
2384 return shared_ptr<Route> ((Route*) 0);
2388 Session::find_current_end ()
2390 if (_state_of_the_state & Loading) {
2394 jack_nframes_t max = get_maximum_extent ();
2396 if (max > end_location->end()) {
2397 end_location->set_end (max);
2399 DurationChanged(); /* EMIT SIGNAL */
2404 Session::get_maximum_extent () const
2406 jack_nframes_t max = 0;
2409 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2411 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2412 Playlist* pl = (*i)->playlist();
2413 if ((me = pl->get_maximum_extent()) > max) {
2421 boost::shared_ptr<Diskstream>
2422 Session::diskstream_by_name (string name)
2424 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2426 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2427 if ((*i)->name() == name) {
2432 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2435 boost::shared_ptr<Diskstream>
2436 Session::diskstream_by_id (const PBD::ID& id)
2438 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2441 if ((*i)->id() == id) {
2446 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2449 /* Region management */
2452 Session::new_region_name (string old)
2454 string::size_type last_period;
2456 string::size_type len = old.length() + 64;
2459 if ((last_period = old.find_last_of ('.')) == string::npos) {
2461 /* no period present - add one explicitly */
2464 last_period = old.length() - 1;
2469 number = atoi (old.substr (last_period+1).c_str());
2473 while (number < (UINT_MAX-1)) {
2475 RegionList::const_iterator i;
2480 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2483 for (i = regions.begin(); i != regions.end(); ++i) {
2484 if (i->second->name() == sbuf) {
2489 if (i == regions.end()) {
2494 if (number != (UINT_MAX-1)) {
2498 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2503 Session::region_name (string& result, string base, bool newlevel) const
2508 assert(base.find("/") == string::npos);
2512 Glib::Mutex::Lock lm (region_lock);
2514 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2522 /* XXX this is going to be slow. optimize me later */
2527 string::size_type pos;
2529 pos = base.find_last_of ('.');
2531 /* pos may be npos, but then we just use entire base */
2533 subbase = base.substr (0, pos);
2537 bool name_taken = true;
2540 Glib::Mutex::Lock lm (region_lock);
2542 for (int n = 1; n < 5000; ++n) {
2545 snprintf (buf, sizeof (buf), ".%d", n);
2550 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2551 if (i->second->name() == result) {
2564 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2572 Session::add_region (boost::shared_ptr<Region> region)
2574 boost::shared_ptr<Region> other;
2578 Glib::Mutex::Lock lm (region_lock);
2580 RegionList::iterator x;
2582 for (x = regions.begin(); x != regions.end(); ++x) {
2586 if (region->region_list_equivalent (other)) {
2591 if (x == regions.end()) {
2593 pair<RegionList::key_type,RegionList::mapped_type> entry;
2595 entry.first = region->id();
2596 entry.second = region;
2598 pair<RegionList::iterator,bool> x = regions.insert (entry);
2610 /* mark dirty because something has changed even if we didn't
2611 add the region to the region list.
2617 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2618 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2619 RegionAdded (region); /* EMIT SIGNAL */
2624 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2626 if (what_changed & Region::HiddenChanged) {
2627 /* relay hidden changes */
2628 RegionHiddenChange (region);
2633 Session::region_renamed (boost::shared_ptr<Region> region)
2635 add_region (region);
2639 Session::remove_region (boost::shared_ptr<Region> region)
2641 RegionList::iterator i;
2642 bool removed = false;
2645 Glib::Mutex::Lock lm (region_lock);
2647 if ((i = regions.find (region->id())) != regions.end()) {
2653 /* mark dirty because something has changed even if we didn't
2654 remove the region from the region list.
2660 RegionRemoved(region); /* EMIT SIGNAL */
2664 boost::shared_ptr<Region>
2665 Session::find_whole_file_parent (Region& child)
2667 RegionList::iterator i;
2668 boost::shared_ptr<Region> region;
2670 Glib::Mutex::Lock lm (region_lock);
2672 for (i = regions.begin(); i != regions.end(); ++i) {
2676 if (region->whole_file()) {
2678 if (child.source_equivalent (region)) {
2684 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2688 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2690 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2691 (*i)->get_region_list_equivalent_regions (region, result);
2695 Session::destroy_region (boost::shared_ptr<Region> region)
2697 boost::shared_ptr<AudioRegion> aregion;
2699 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2703 if (aregion->playlist()) {
2704 aregion->playlist()->destroy_region (region);
2707 vector<boost::shared_ptr<Source> > srcs;
2709 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2710 srcs.push_back (aregion->source (n));
2713 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2715 if ((*i).use_count() == 1) {
2716 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2719 (afs)->mark_for_remove ();
2722 (*i)->drop_references ();
2730 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2732 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2733 destroy_region (*i);
2739 Session::remove_last_capture ()
2741 list<boost::shared_ptr<Region> > r;
2743 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2745 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2746 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2749 r.insert (r.end(), l.begin(), l.end());
2754 destroy_regions (r);
2759 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2765 /* Source Management */
2767 Session::add_source (boost::shared_ptr<Source> source)
2769 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2770 pair<SourceMap::iterator,bool> result;
2772 entry.first = source->id();
2773 entry.second = source;
2776 Glib::Mutex::Lock lm (source_lock);
2777 result = sources.insert (entry);
2780 if (!result.second) {
2781 cerr << "\tNOT inserted ? " << result.second << endl;
2784 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2787 SourceAdded (source); /* EMIT SIGNAL */
2791 Session::remove_source (boost::weak_ptr<Source> src)
2793 SourceMap::iterator i;
2794 boost::shared_ptr<Source> source = src.lock();
2797 cerr << "removing a source DEAD\n";
2799 cerr << "removing a source " << source->name () << endl;
2802 Glib::Mutex::Lock lm (source_lock);
2804 if ((i = sources.find (source->id())) != sources.end()) {
2809 if (!_state_of_the_state & InCleanup) {
2811 /* save state so we don't end up with a session file
2812 referring to non-existent sources.
2815 save_state (_current_snapshot_name);
2818 SourceRemoved(source); /* EMIT SIGNAL */
2822 boost::shared_ptr<Source>
2823 Session::source_by_id (const PBD::ID& id)
2825 Glib::Mutex::Lock lm (source_lock);
2826 SourceMap::iterator i;
2827 boost::shared_ptr<Source> source;
2829 if ((i = sources.find (id)) != sources.end()) {
2833 /* XXX search MIDI or other searches here */
2839 Session::peak_path_from_audio_path (string audio_path)
2841 /* XXX hardly bombproof! fix me */
2845 res = Glib::path_get_dirname (audio_path);
2846 res = Glib::path_get_dirname (res);
2848 res += peak_dir_name;
2850 res += PBD::basename_nosuffix (audio_path);
2857 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2860 string old_basename = PBD::basename_nosuffix (oldname);
2861 string new_legalized = legalize_for_path (newname);
2863 /* note: we know (or assume) the old path is already valid */
2867 /* destructive file sources have a name of the form:
2869 /path/to/Tnnnn-NAME(%[LR])?.wav
2871 the task here is to replace NAME with the new name.
2874 /* find last slash */
2878 string::size_type slash;
2879 string::size_type dash;
2881 if ((slash = path.find_last_of ('/')) == string::npos) {
2885 dir = path.substr (0, slash+1);
2887 /* '-' is not a legal character for the NAME part of the path */
2889 if ((dash = path.find_last_of ('-')) == string::npos) {
2893 prefix = path.substr (slash+1, dash-(slash+1));
2898 path += new_legalized;
2899 path += ".wav"; /* XXX gag me with a spoon */
2903 /* non-destructive file sources have a name of the form:
2905 /path/to/NAME-nnnnn(%[LR])?.wav
2907 the task here is to replace NAME with the new name.
2912 string::size_type slash;
2913 string::size_type dash;
2914 string::size_type postfix;
2916 /* find last slash */
2918 if ((slash = path.find_last_of ('/')) == string::npos) {
2922 dir = path.substr (0, slash+1);
2924 /* '-' is not a legal character for the NAME part of the path */
2926 if ((dash = path.find_last_of ('-')) == string::npos) {
2930 suffix = path.substr (dash+1);
2932 // Suffix is now everything after the dash. Now we need to eliminate
2933 // the nnnnn part, which is done by either finding a '%' or a '.'
2935 postfix = suffix.find_last_of ("%");
2936 if (postfix == string::npos) {
2937 postfix = suffix.find_last_of ('.');
2940 if (postfix != string::npos) {
2941 suffix = suffix.substr (postfix);
2943 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2947 const uint32_t limit = 10000;
2948 char buf[PATH_MAX+1];
2950 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2952 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2954 if (access (buf, F_OK) != 0) {
2962 error << "FATAL ERROR! Could not find a " << endl;
2971 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2975 char buf[PATH_MAX+1];
2976 const uint32_t limit = 10000;
2980 legalized = legalize_for_path (name);
2982 /* find a "version" of the file name that doesn't exist in
2983 any of the possible directories.
2986 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2988 vector<space_and_path>::iterator i;
2989 uint32_t existing = 0;
2991 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2996 spath += tape_dir_name;
2998 spath += sound_dir_name;
3003 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3004 } else if (nchan == 2) {
3006 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3008 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3010 } else if (nchan < 26) {
3011 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3013 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3021 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3022 } else if (nchan == 2) {
3024 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3026 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3028 } else if (nchan < 26) {
3029 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3031 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3035 if (access (buf, F_OK) == 0) {
3040 if (existing == 0) {
3045 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3046 throw failed_constructor();
3050 /* we now have a unique name for the file, but figure out where to
3057 spath = tape_dir ();
3059 spath = discover_best_sound_dir ();
3062 string::size_type pos = foo.find_last_of ('/');
3064 if (pos == string::npos) {
3067 spath += foo.substr (pos + 1);
3073 boost::shared_ptr<AudioFileSource>
3074 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3076 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3077 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, spath, destructive, frame_rate()));
3080 // FIXME: _terrible_ code duplication
3082 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3085 string old_basename = PBD::basename_nosuffix (oldname);
3086 string new_legalized = legalize_for_path (newname);
3088 /* note: we know (or assume) the old path is already valid */
3092 /* destructive file sources have a name of the form:
3094 /path/to/Tnnnn-NAME(%[LR])?.wav
3096 the task here is to replace NAME with the new name.
3099 /* find last slash */
3103 string::size_type slash;
3104 string::size_type dash;
3106 if ((slash = path.find_last_of ('/')) == string::npos) {
3110 dir = path.substr (0, slash+1);
3112 /* '-' is not a legal character for the NAME part of the path */
3114 if ((dash = path.find_last_of ('-')) == string::npos) {
3118 prefix = path.substr (slash+1, dash-(slash+1));
3123 path += new_legalized;
3124 path += ".mid"; /* XXX gag me with a spoon */
3128 /* non-destructive file sources have a name of the form:
3130 /path/to/NAME-nnnnn(%[LR])?.wav
3132 the task here is to replace NAME with the new name.
3137 string::size_type slash;
3138 string::size_type dash;
3139 string::size_type postfix;
3141 /* find last slash */
3143 if ((slash = path.find_last_of ('/')) == string::npos) {
3147 dir = path.substr (0, slash+1);
3149 /* '-' is not a legal character for the NAME part of the path */
3151 if ((dash = path.find_last_of ('-')) == string::npos) {
3155 suffix = path.substr (dash+1);
3157 // Suffix is now everything after the dash. Now we need to eliminate
3158 // the nnnnn part, which is done by either finding a '%' or a '.'
3160 postfix = suffix.find_last_of ("%");
3161 if (postfix == string::npos) {
3162 postfix = suffix.find_last_of ('.');
3165 if (postfix != string::npos) {
3166 suffix = suffix.substr (postfix);
3168 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3172 const uint32_t limit = 10000;
3173 char buf[PATH_MAX+1];
3175 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3177 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3179 if (access (buf, F_OK) != 0) {
3187 error << "FATAL ERROR! Could not find a " << endl;
3196 Session::midi_path_from_name (string name)
3200 char buf[PATH_MAX+1];
3201 const uint32_t limit = 10000;
3205 legalized = legalize_for_path (name);
3207 /* find a "version" of the file name that doesn't exist in
3208 any of the possible directories.
3211 for (cnt = 1; cnt <= limit; ++cnt) {
3213 vector<space_and_path>::iterator i;
3214 uint32_t existing = 0;
3216 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3218 // FIXME: different directory from audio?
3219 spath = (*i).path + sound_dir_name + "/" + legalized;
3221 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3223 if (access (buf, F_OK) == 0) {
3228 if (existing == 0) {
3233 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3234 throw failed_constructor();
3238 /* we now have a unique name for the file, but figure out where to
3244 // FIXME: different directory than audio?
3245 spath = discover_best_sound_dir ();
3247 string::size_type pos = foo.find_last_of ('/');
3249 if (pos == string::npos) {
3252 spath += foo.substr (pos + 1);
3258 boost::shared_ptr<MidiSource>
3259 Session::create_midi_source_for_session (MidiDiskstream& ds)
3261 string spath = midi_path_from_name (ds.name());
3263 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, spath, false, frame_rate()));
3267 /* Playlist management */
3270 Session::playlist_by_name (string name)
3272 Glib::Mutex::Lock lm (playlist_lock);
3273 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3274 if ((*i)->name() == name) {
3278 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3279 if ((*i)->name() == name) {
3287 Session::add_playlist (Playlist* playlist)
3289 if (playlist->hidden()) {
3294 Glib::Mutex::Lock lm (playlist_lock);
3295 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3296 playlists.insert (playlists.begin(), playlist);
3298 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3299 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3305 PlaylistAdded (playlist); /* EMIT SIGNAL */
3309 Session::track_playlist (Playlist* pl, bool inuse)
3311 PlaylistList::iterator x;
3314 Glib::Mutex::Lock lm (playlist_lock);
3317 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3319 unused_playlists.insert (pl);
3321 if ((x = playlists.find (pl)) != playlists.end()) {
3322 playlists.erase (x);
3327 //cerr << "shifting playlist to used: " << pl->name() << endl;
3329 playlists.insert (pl);
3331 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3332 unused_playlists.erase (x);
3339 Session::remove_playlist (Playlist* playlist)
3341 if (_state_of_the_state & Deletion) {
3346 Glib::Mutex::Lock lm (playlist_lock);
3347 // cerr << "removing playlist: " << playlist->name() << endl;
3349 PlaylistList::iterator i;
3351 i = find (playlists.begin(), playlists.end(), playlist);
3353 if (i != playlists.end()) {
3354 playlists.erase (i);
3357 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3358 if (i != unused_playlists.end()) {
3359 unused_playlists.erase (i);
3366 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3370 Session::set_audition (boost::shared_ptr<Region> r)
3372 pending_audition_region = r;
3373 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3374 schedule_butler_transport_work ();
3378 Session::audition_playlist ()
3380 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3381 ev->region.reset ();
3386 Session::non_realtime_set_audition ()
3388 if (!pending_audition_region) {
3389 auditioner->audition_current_playlist ();
3391 auditioner->audition_region (pending_audition_region);
3392 pending_audition_region.reset ();
3394 AuditionActive (true); /* EMIT SIGNAL */
3398 Session::audition_region (boost::shared_ptr<Region> r)
3400 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3406 Session::cancel_audition ()
3408 if (auditioner->active()) {
3409 auditioner->cancel_audition ();
3410 AuditionActive (false); /* EMIT SIGNAL */
3415 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3417 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3421 Session::remove_empty_sounds ()
3424 PathScanner scanner;
3429 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3431 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3433 if (AudioFileSource::is_empty (*(*i))) {
3435 unlink ((*i)->c_str());
3437 string peak_path = peak_path_from_audio_path (**i);
3438 unlink (peak_path.c_str());
3444 delete possible_audiofiles;
3448 Session::is_auditioning () const
3450 /* can be called before we have an auditioner object */
3452 return auditioner->active();
3459 Session::set_all_solo (bool yn)
3461 shared_ptr<RouteList> r = routes.reader ();
3463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3464 if (!(*i)->hidden()) {
3465 (*i)->set_solo (yn, this);
3473 Session::set_all_mute (bool yn)
3475 shared_ptr<RouteList> r = routes.reader ();
3477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3478 if (!(*i)->hidden()) {
3479 (*i)->set_mute (yn, this);
3487 Session::n_diskstreams () const
3491 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3493 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3494 if (!(*i)->hidden()) {
3502 Session::graph_reordered ()
3504 /* don't do this stuff if we are setting up connections
3505 from a set_state() call.
3508 if (_state_of_the_state & InitialConnecting) {
3514 /* force all diskstreams to update their capture offset values to
3515 reflect any changes in latencies within the graph.
3518 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3520 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3521 (*i)->set_capture_offset ();
3526 Session::record_disenable_all ()
3528 record_enable_change_all (false);
3532 Session::record_enable_all ()
3534 record_enable_change_all (true);
3538 Session::record_enable_change_all (bool yn)
3540 shared_ptr<RouteList> r = routes.reader ();
3542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3545 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3546 at->set_record_enable (yn, this);
3550 /* since we don't keep rec-enable state, don't mark session dirty */
3554 Session::add_redirect (Redirect* redirect)
3558 PortInsert* port_insert;
3559 PluginInsert* plugin_insert;
3561 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3562 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3563 _port_inserts.insert (_port_inserts.begin(), port_insert);
3564 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3565 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3567 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3570 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3571 _sends.insert (_sends.begin(), send);
3573 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3577 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3583 Session::remove_redirect (Redirect* redirect)
3587 PortInsert* port_insert;
3588 PluginInsert* plugin_insert;
3590 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3591 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3592 _port_inserts.remove (port_insert);
3593 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3594 _plugin_inserts.remove (plugin_insert);
3596 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3599 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3600 _sends.remove (send);
3602 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3610 Session::available_capture_duration ()
3612 const double scale = 4096.0 / sizeof (Sample);
3614 if (_total_free_4k_blocks * scale > (double) max_frames) {
3618 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3622 Session::add_connection (ARDOUR::Connection* connection)
3625 Glib::Mutex::Lock guard (connection_lock);
3626 _connections.push_back (connection);
3629 ConnectionAdded (connection); /* EMIT SIGNAL */
3635 Session::remove_connection (ARDOUR::Connection* connection)
3637 bool removed = false;
3640 Glib::Mutex::Lock guard (connection_lock);
3641 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3643 if (i != _connections.end()) {
3644 _connections.erase (i);
3650 ConnectionRemoved (connection); /* EMIT SIGNAL */
3656 ARDOUR::Connection *
3657 Session::connection_by_name (string name) const
3659 Glib::Mutex::Lock lm (connection_lock);
3661 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3662 if ((*i)->name() == name) {
3671 Session::set_edit_mode (EditMode mode)
3676 Glib::Mutex::Lock lm (playlist_lock);
3678 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3679 (*i)->set_edit_mode (mode);
3684 ControlChanged (EditingMode); /* EMIT SIGNAL */
3688 Session::tempo_map_changed (Change ignored)
3694 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3695 * the given count with the current block size.
3698 Session::ensure_buffers (ChanCount howmany)
3700 // FIXME: NASTY assumption (midi block size == audio block size)
3701 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3702 _send_buffers->ensure_buffers(howmany, current_block_size);
3703 _silent_buffers->ensure_buffers(howmany, current_block_size);
3705 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3709 Session::next_send_name ()
3712 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3717 Session::next_insert_name ()
3720 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3724 /* Named Selection management */
3727 Session::named_selection_by_name (string name)
3729 Glib::Mutex::Lock lm (named_selection_lock);
3730 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3731 if ((*i)->name == name) {
3739 Session::add_named_selection (NamedSelection* named_selection)
3742 Glib::Mutex::Lock lm (named_selection_lock);
3743 named_selections.insert (named_selections.begin(), named_selection);
3748 NamedSelectionAdded (); /* EMIT SIGNAL */
3752 Session::remove_named_selection (NamedSelection* named_selection)
3754 bool removed = false;
3757 Glib::Mutex::Lock lm (named_selection_lock);
3759 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3761 if (i != named_selections.end()) {
3763 named_selections.erase (i);
3770 NamedSelectionRemoved (); /* EMIT SIGNAL */
3775 Session::reset_native_file_format ()
3777 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3779 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3780 (*i)->reset_write_sources (false);
3785 Session::route_name_unique (string n) const
3787 shared_ptr<RouteList> r = routes.reader ();
3789 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3790 if ((*i)->name() == n) {
3799 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3801 return fs->move_to_trash (dead_sound_dir_name);
3805 Session::n_playlists () const
3807 Glib::Mutex::Lock lm (playlist_lock);
3808 return playlists.size();
3812 Session::set_solo_model (SoloModel sm)
3814 if (sm != _solo_model) {
3816 ControlChanged (SoloingModel);
3822 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3824 if (!force && howmany <= _npan_buffers) {
3828 if (_pan_automation_buffer) {
3830 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3831 delete [] _pan_automation_buffer[i];
3834 delete [] _pan_automation_buffer;
3837 _pan_automation_buffer = new pan_t*[howmany];
3839 for (uint32_t i = 0; i < howmany; ++i) {
3840 _pan_automation_buffer[i] = new pan_t[nframes];
3843 _npan_buffers = howmany;
3847 Session::freeze (InterThreadInfo& itt)
3849 shared_ptr<RouteList> r = routes.reader ();
3851 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3855 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3856 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3867 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3868 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3870 boost::shared_ptr<AudioFileSource> fsource;
3873 Playlist* playlist = 0;
3875 char buf[PATH_MAX+1];
3877 ChanCount nchans(track.audio_diskstream()->n_channels());
3878 jack_nframes_t position;
3879 jack_nframes_t this_chunk;
3880 jack_nframes_t to_do;
3883 // any bigger than this seems to cause stack overflows in called functions
3884 const jack_nframes_t chunk_size = (128 * 1024)/4;
3886 g_atomic_int_set (&processing_prohibited, 1);
3888 /* call tree *MUST* hold route_lock */
3890 if ((playlist = track.diskstream()->playlist()) == 0) {
3894 /* external redirects will be a problem */
3896 if (track.has_external_redirects()) {
3900 dir = discover_best_sound_dir ();
3902 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3904 for (x = 0; x < 99999; ++x) {
3905 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3906 if (access (buf, F_OK) != 0) {
3912 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3917 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, buf, false, frame_rate()));
3920 catch (failed_constructor& err) {
3921 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3925 srcs.push_back (fsource);
3928 /* XXX need to flush all redirects */
3933 /* create a set of reasonably-sized buffers */
3934 buffers.ensure_buffers(nchans, chunk_size);
3935 buffers.set_count(nchans);
3937 while (to_do && !itt.cancel) {
3939 this_chunk = min (to_do, chunk_size);
3941 if (track.export_stuff (buffers, start, this_chunk)) {
3946 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3947 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3950 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
3956 start += this_chunk;
3957 to_do -= this_chunk;
3959 itt.progress = (float) (1.0 - ((double) to_do / len));
3968 xnow = localtime (&now);
3970 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3971 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3974 afs->update_header (position, *xnow, now);
3978 /* build peakfile for new source */
3980 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3981 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3983 afs->build_peaks ();
3992 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3993 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3996 afs->mark_for_remove ();
3999 (*src)->drop_references ();
4003 g_atomic_int_set (&processing_prohibited, 0);
4011 Session::get_silent_buffers (ChanCount count)
4013 assert(_silent_buffers->available() >= count);
4014 _silent_buffers->set_count(count);
4016 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4017 for (size_t i=0; i < count.get(*t); ++i) {
4018 _silent_buffers->get(*t, i).clear();
4022 return *_silent_buffers;
4026 Session::get_scratch_buffers (ChanCount count)
4028 assert(_scratch_buffers->available() >= count);
4029 _scratch_buffers->set_count(count);
4030 return *_scratch_buffers;
4034 Session::get_send_buffers (ChanCount count)
4036 assert(_send_buffers->available() >= count);
4037 _send_buffers->set_count(count);
4038 return *_send_buffers;
4042 Session::ntracks () const
4045 shared_ptr<RouteList> r = routes.reader ();
4047 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4048 if (dynamic_cast<Track*> ((*i).get())) {
4057 Session::nbusses () const
4060 shared_ptr<RouteList> r = routes.reader ();
4062 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4063 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4072 Session::set_layer_model (LayerModel lm)
4074 if (lm != layer_model) {
4077 ControlChanged (LayeringModel);
4082 Session::set_xfade_model (CrossfadeModel xm)
4084 if (xm != xfade_model) {
4087 ControlChanged (CrossfadingModel);
4092 Session::handle_configuration_change (const char* parameter)
4094 if (!strcmp (parameter, "use-video-sync")) {
4095 if (_transport_speed == 0.0f) {
4096 waiting_for_sync_offset = true;
4102 Session::add_curve(Curve *curve)
4104 curves[curve->id()] = curve;
4108 Session::add_automation_list(AutomationList *al)
4110 automation_lists[al->id()] = al;