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>
69 #include <ardour/osc.h>
75 using namespace ARDOUR;
78 const char* Session::_template_suffix = X_(".template");
79 const char* Session::_statefile_suffix = X_(".ardour");
80 const char* Session::_pending_suffix = X_(".pending");
81 const char* Session::sound_dir_name = X_("sounds");
82 const char* Session::tape_dir_name = X_("tapes");
83 const char* Session::peak_dir_name = X_("peaks");
84 const char* Session::dead_sound_dir_name = X_("dead_sounds");
86 Session::compute_peak_t Session::compute_peak = 0;
87 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
88 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
89 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
91 sigc::signal<int> Session::AskAboutPendingState;
92 sigc::signal<void> Session::SMPTEOffsetChanged;
93 sigc::signal<void> Session::SendFeedback;
97 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
100 char buf[PATH_MAX+1];
104 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
105 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
111 /* check to see if it exists, and what it is */
113 if (stat (str.c_str(), &statbuf)) {
114 if (errno == ENOENT) {
117 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
125 /* it exists, so it must either be the name
126 of the directory, or the name of the statefile
130 if (S_ISDIR (statbuf.st_mode)) {
132 string::size_type slash = str.find_last_of ('/');
134 if (slash == string::npos) {
136 /* a subdirectory of cwd, so statefile should be ... */
142 tmp += _statefile_suffix;
146 if (stat (tmp.c_str(), &statbuf)) {
147 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
157 /* some directory someplace in the filesystem.
158 the snapshot name is the directory name
163 snapshot = str.substr (slash+1);
167 } else if (S_ISREG (statbuf.st_mode)) {
169 string::size_type slash = str.find_last_of ('/');
170 string::size_type suffix;
172 /* remove the suffix */
174 if (slash != string::npos) {
175 snapshot = str.substr (slash+1);
180 suffix = snapshot.find (_statefile_suffix);
182 if (suffix == string::npos) {
183 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
189 snapshot = snapshot.substr (0, suffix);
191 if (slash == string::npos) {
193 /* we must be in the directory where the
194 statefile lives. get it using cwd().
197 char cwd[PATH_MAX+1];
199 if (getcwd (cwd, sizeof (cwd)) == 0) {
200 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
209 /* full path to the statefile */
211 path = str.substr (0, slash);
216 /* what type of file is it? */
217 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
223 /* its the name of a new directory. get the name
227 string::size_type slash = str.find_last_of ('/');
229 if (slash == string::npos) {
231 /* no slash, just use the name, but clean it up */
233 path = legalize_for_path (str);
239 snapshot = str.substr (slash+1);
246 Session::Session (AudioEngine &eng,
248 string snapshot_name,
249 string* mix_template)
252 _mmc_port (default_mmc_port),
253 _mtc_port (default_mtc_port),
254 _midi_port (default_midi_port),
255 pending_events (2048),
256 midi_requests (128), // the size of this should match the midi request pool size
261 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
263 n_physical_outputs = _engine.n_physical_outputs();
264 n_physical_inputs = _engine.n_physical_inputs();
266 first_stage_init (fullpath, snapshot_name);
268 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
269 throw failed_constructor ();
272 if (second_stage_init (new_session)) {
273 throw failed_constructor ();
276 store_recent_sessions(_name, _path);
278 bool was_dirty = dirty();
280 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
283 DirtyChanged (); /* EMIT SIGNAL */
287 Session::Session (AudioEngine &eng,
289 string snapshot_name,
290 AutoConnectOption input_ac,
291 AutoConnectOption output_ac,
292 uint32_t control_out_channels,
293 uint32_t master_out_channels,
294 uint32_t requested_physical_in,
295 uint32_t requested_physical_out,
296 jack_nframes_t initial_length)
299 _mmc_port (default_mmc_port),
300 _mtc_port (default_mtc_port),
301 _midi_port (default_midi_port),
302 pending_events (2048),
309 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
311 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
312 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
314 first_stage_init (fullpath, snapshot_name);
316 if (create (new_session, 0, initial_length)) {
317 throw failed_constructor ();
320 if (control_out_channels) {
322 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
327 if (master_out_channels) {
329 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
333 /* prohibit auto-connect to master, because there isn't one */
334 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
337 input_auto_connect = input_ac;
338 output_auto_connect = output_ac;
340 if (second_stage_init (new_session)) {
341 throw failed_constructor ();
344 store_recent_sessions(_name, _path);
346 bool was_dirty = dirty ();
348 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
351 DirtyChanged (); /* EMIT SIGNAL */
357 /* if we got to here, leaving pending capture state around
361 remove_pending_capture_state ();
363 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
364 _engine.remove_session ();
366 going_away (); /* EMIT SIGNAL */
368 terminate_butler_thread ();
369 terminate_midi_thread ();
371 if (click_data && click_data != default_click) {
372 delete [] click_data;
375 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
376 delete [] click_emphasis_data;
390 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
394 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
398 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
402 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
403 delete [] (i->second);
406 #undef TRACK_DESTRUCTION
407 #ifdef TRACK_DESTRUCTION
408 cerr << "delete named selections\n";
409 #endif /* TRACK_DESTRUCTION */
410 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
411 NamedSelectionList::iterator tmp;
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete playlists\n";
422 #endif /* TRACK_DESTRUCTION */
423 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
424 PlaylistList::iterator tmp;
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete audio regions\n";
436 #endif /* TRACK_DESTRUCTION */
437 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
438 AudioRegionList::iterator tmp;
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete routes\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
452 RouteList::iterator tmp;
459 #ifdef TRACK_DESTRUCTION
460 cerr << "delete audio_diskstreams\n";
461 #endif /* TRACK_DESTRUCTION */
462 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
463 AudioDiskstreamList::iterator tmp;
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete audio sources\n";
475 #endif /* TRACK_DESTRUCTION */
476 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
477 AudioSourceList::iterator tmp;
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete mix groups\n";
489 #endif /* TRACK_DESTRUCTION */
490 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
491 list<RouteGroup*>::iterator tmp;
501 #ifdef TRACK_DESTRUCTION
502 cerr << "delete edit groups\n";
503 #endif /* TRACK_DESTRUCTION */
504 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
505 list<RouteGroup*>::iterator tmp;
515 #ifdef TRACK_DESTRUCTION
516 cerr << "delete connections\n";
517 #endif /* TRACK_DESTRUCTION */
518 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
519 ConnectionList::iterator tmp;
529 if (butler_mixdown_buffer) {
530 delete [] butler_mixdown_buffer;
533 if (butler_gain_buffer) {
534 delete [] butler_gain_buffer;
537 Crossfade::set_buffer_size (0);
549 Session::set_worst_io_latencies (bool take_lock)
551 _worst_output_latency = 0;
552 _worst_input_latency = 0;
554 if (!_engine.connected()) {
559 route_lock.reader_lock ();
562 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
563 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
564 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
568 route_lock.reader_unlock ();
573 Session::when_engine_running ()
575 string first_physical_output;
577 /* we don't want to run execute this again */
579 first_time_running.disconnect ();
581 set_block_size (_engine.frames_per_cycle());
582 set_frame_rate (_engine.frame_rate());
584 /* every time we reconnect, recompute worst case output latencies */
586 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
588 if (synced_to_jack()) {
589 _engine.transport_stop ();
592 if (Config->get_jack_time_master()) {
593 _engine.transport_locate (_transport_frame);
601 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
603 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
605 /* existing state for Click */
607 if (_click_io->set_state (*child->children().front()) == 0) {
609 _clicking = click_requested;
613 error << _("could not setup Click I/O") << endmsg;
619 /* default state for Click */
621 first_physical_output = _engine.get_nth_physical_output (0);
623 if (first_physical_output.length()) {
624 if (_click_io->add_output_port (first_physical_output, this)) {
625 // relax, even though its an error
627 _clicking = click_requested;
633 catch (failed_constructor& err) {
634 error << _("cannot setup Click I/O") << endmsg;
637 set_worst_io_latencies (true);
640 ControlChanged (Clicking); /* EMIT SIGNAL */
643 if (auditioner == 0) {
645 /* we delay creating the auditioner till now because
646 it makes its own connections to ports named
647 in the ARDOUR_RC config file. the engine has
648 to be running for this to work.
652 auditioner = new Auditioner (*this);
655 catch (failed_constructor& err) {
656 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
660 /* Create a set of Connection objects that map
661 to the physical outputs currently available
666 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
668 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
670 Connection* c = new OutputConnection (buf, true);
673 c->add_connection (0, _engine.get_nth_physical_output (np));
678 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
680 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
682 Connection* c = new InputConnection (buf, true);
685 c->add_connection (0, _engine.get_nth_physical_input (np));
692 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
694 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
696 Connection* c = new OutputConnection (buf, true);
700 c->add_connection (0, _engine.get_nth_physical_output (np));
701 c->add_connection (1, _engine.get_nth_physical_output (np+1));
706 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
708 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
710 Connection* c = new InputConnection (buf, true);
714 c->add_connection (0, _engine.get_nth_physical_input (np));
715 c->add_connection (1, _engine.get_nth_physical_input (np+1));
724 /* create master/control ports */
729 /* force the master to ignore any later call to this */
731 if (_master_out->pending_state_node) {
732 _master_out->ports_became_legal();
735 /* no panner resets till we are through */
737 _master_out->defer_pan_reset ();
739 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
740 if (_master_out->add_input_port ("", this)) {
741 error << _("cannot setup master inputs")
747 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
748 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
749 error << _("cannot setup master outputs")
756 _master_out->allow_pan_reset ();
760 Connection* c = new OutputConnection (_("Master Out"), true);
762 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
764 c->add_connection ((int) n, _master_out->input(n)->name());
771 /* catch up on send+insert cnts */
775 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
778 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
779 if (id > insert_cnt) {
787 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
790 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
797 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
799 /* hook us up to the engine */
801 _engine.set_session (this);
806 osc->set_session (*this);
809 _state_of_the_state = Clean;
811 DirtyChanged (); /* EMIT SIGNAL */
815 Session::hookup_io ()
817 /* stop graph reordering notifications from
818 causing resorts, etc.
821 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
823 /* Tell all IO objects to create their ports */
830 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
831 if (_control_out->add_input_port ("", this)) {
832 error << _("cannot setup control inputs")
838 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
839 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
840 error << _("cannot set up master outputs")
848 /* Tell all IO objects to connect themselves together */
850 IO::enable_connecting ();
852 /* Now reset all panners */
854 IO::reset_panners ();
856 /* Anyone who cares about input state, wake up and do something */
858 IOConnectionsComplete (); /* EMIT SIGNAL */
860 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
862 /* now handle the whole enchilada as if it was one
868 /* update mixer solo state */
874 Session::playlist_length_changed (Playlist* pl)
876 /* we can't just increase end_location->end() if pl->get_maximum_extent()
877 if larger. if the playlist used to be the longest playlist,
878 and its now shorter, we have to decrease end_location->end(). hence,
879 we have to iterate over all diskstreams and check the
880 playlists currently in use.
886 Session::diskstream_playlist_changed (AudioDiskstream* dstream)
890 if ((playlist = dstream->playlist()) != 0) {
891 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
894 /* see comment in playlist_length_changed () */
899 Session::record_enabling_legal () const
901 /* this used to be in here, but survey says.... we don't need to restrict it */
902 // if (record_status() == Recording) {
913 Session::set_auto_play (bool yn)
915 if (auto_play != yn) {
918 ControlChanged (AutoPlay);
923 Session::set_auto_return (bool yn)
925 if (auto_return != yn) {
928 ControlChanged (AutoReturn);
933 Session::set_crossfades_active (bool yn)
935 if (crossfades_active != yn) {
936 crossfades_active = yn;
938 ControlChanged (CrossFadesActive);
943 Session::set_do_not_record_plugins (bool yn)
945 if (do_not_record_plugins != yn) {
946 do_not_record_plugins = yn;
948 ControlChanged (RecordingPlugins);
953 Session::set_auto_input (bool yn)
955 if (auto_input != yn) {
958 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
959 /* auto-input only makes a difference if we're rolling */
961 /* Even though this can called from RT context we are using
962 a non-tentative rwlock here, because the action must occur.
963 The rarity and short potential lock duration makes this "OK"
965 Glib::RWLock::ReaderLock dsm (diskstream_lock);
966 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
967 if ((*i)->record_enabled ()) {
968 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
969 (*i)->monitor_input (!auto_input);
975 ControlChanged (AutoInput);
980 Session::reset_input_monitor_state ()
982 if (transport_rolling()) {
983 Glib::RWLock::ReaderLock dsm (diskstream_lock);
984 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
985 if ((*i)->record_enabled ()) {
986 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
987 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
991 Glib::RWLock::ReaderLock dsm (diskstream_lock);
992 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
993 if ((*i)->record_enabled ()) {
994 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
995 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1003 Session::set_input_auto_connect (bool yn)
1006 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1008 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1014 Session::get_input_auto_connect () const
1016 return (input_auto_connect & AutoConnectPhysical);
1020 Session::set_output_auto_connect (AutoConnectOption aco)
1022 output_auto_connect = aco;
1027 Session::auto_punch_start_changed (Location* location)
1029 replace_event (Event::PunchIn, location->start());
1031 if (get_record_enabled() && get_punch_in()) {
1032 /* capture start has been changed, so save new pending state */
1033 save_state ("", true);
1038 Session::auto_punch_end_changed (Location* location)
1040 jack_nframes_t when_to_stop = location->end();
1041 // when_to_stop += _worst_output_latency + _worst_input_latency;
1042 replace_event (Event::PunchOut, when_to_stop);
1046 Session::auto_punch_changed (Location* location)
1048 jack_nframes_t when_to_stop = location->end();
1050 replace_event (Event::PunchIn, location->start());
1051 //when_to_stop += _worst_output_latency + _worst_input_latency;
1052 replace_event (Event::PunchOut, when_to_stop);
1056 Session::auto_loop_changed (Location* location)
1058 replace_event (Event::AutoLoop, location->end(), location->start());
1060 if (transport_rolling() && get_auto_loop()) {
1062 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1064 if (_transport_frame > location->end()) {
1065 // relocate to beginning of loop
1066 clear_events (Event::LocateRoll);
1068 request_locate (location->start(), true);
1071 else if (seamless_loop && !loop_changing) {
1073 // schedule a locate-roll to refill the audio_diskstreams at the
1074 // previous loop end
1075 loop_changing = true;
1077 if (location->end() > last_loopend) {
1078 clear_events (Event::LocateRoll);
1079 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1086 last_loopend = location->end();
1091 Session::set_auto_punch_location (Location* location)
1095 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1096 auto_punch_start_changed_connection.disconnect();
1097 auto_punch_end_changed_connection.disconnect();
1098 auto_punch_changed_connection.disconnect();
1099 existing->set_auto_punch (false, this);
1100 remove_event (existing->start(), Event::PunchIn);
1101 clear_events (Event::PunchOut);
1102 auto_punch_location_changed (0);
1107 if (location == 0) {
1111 if (location->end() <= location->start()) {
1112 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1116 auto_punch_start_changed_connection.disconnect();
1117 auto_punch_end_changed_connection.disconnect();
1118 auto_punch_changed_connection.disconnect();
1120 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1121 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1122 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1124 location->set_auto_punch (true, this);
1125 auto_punch_location_changed (location);
1129 Session::set_punch_in (bool yn)
1131 if (punch_in == yn) {
1137 if ((location = _locations.auto_punch_location()) != 0) {
1138 if ((punch_in = yn) == true) {
1139 replace_event (Event::PunchIn, location->start());
1141 remove_event (location->start(), Event::PunchIn);
1146 ControlChanged (PunchIn); /* EMIT SIGNAL */
1150 Session::set_punch_out (bool yn)
1152 if (punch_out == yn) {
1158 if ((location = _locations.auto_punch_location()) != 0) {
1159 if ((punch_out = yn) == true) {
1160 replace_event (Event::PunchOut, location->end());
1162 clear_events (Event::PunchOut);
1167 ControlChanged (PunchOut); /* EMIT SIGNAL */
1171 Session::set_auto_loop_location (Location* location)
1175 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1176 auto_loop_start_changed_connection.disconnect();
1177 auto_loop_end_changed_connection.disconnect();
1178 auto_loop_changed_connection.disconnect();
1179 existing->set_auto_loop (false, this);
1180 remove_event (existing->end(), Event::AutoLoop);
1181 auto_loop_location_changed (0);
1186 if (location == 0) {
1190 if (location->end() <= location->start()) {
1191 error << _("Session: you can't use a mark for auto loop") << endmsg;
1195 last_loopend = location->end();
1197 auto_loop_start_changed_connection.disconnect();
1198 auto_loop_end_changed_connection.disconnect();
1199 auto_loop_changed_connection.disconnect();
1201 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1202 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1203 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1205 location->set_auto_loop (true, this);
1206 auto_loop_location_changed (location);
1210 Session::locations_added (Location* ignored)
1216 Session::locations_changed ()
1218 _locations.apply (*this, &Session::handle_locations_changed);
1222 Session::handle_locations_changed (Locations::LocationList& locations)
1224 Locations::LocationList::iterator i;
1226 bool set_loop = false;
1227 bool set_punch = false;
1229 for (i = locations.begin(); i != locations.end(); ++i) {
1233 if (location->is_auto_punch()) {
1234 set_auto_punch_location (location);
1237 if (location->is_auto_loop()) {
1238 set_auto_loop_location (location);
1245 set_auto_loop_location (0);
1248 set_auto_punch_location (0);
1255 Session::enable_record ()
1257 /* XXX really atomic compare+swap here */
1258 if (g_atomic_int_get (&_record_status) != Recording) {
1259 g_atomic_int_set (&_record_status, Recording);
1260 _last_record_location = _transport_frame;
1261 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1263 if (Config->get_use_hardware_monitoring() && auto_input) {
1264 /* Even though this can be called from RT context we are using
1265 a non-tentative rwlock here, because the action must occur.
1266 The rarity and short potential lock duration makes this "OK"
1268 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1270 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1271 if ((*i)->record_enabled ()) {
1272 (*i)->monitor_input (true);
1277 RecordStateChanged ();
1282 Session::disable_record (bool rt_context, bool force)
1286 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1288 if (!Config->get_latched_record_enable () || force) {
1289 g_atomic_int_set (&_record_status, Disabled);
1291 if (rs == Recording) {
1292 g_atomic_int_set (&_record_status, Enabled);
1296 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1298 if (Config->get_use_hardware_monitoring() && auto_input) {
1299 /* Even though this can be called from RT context we are using
1300 a non-tentative rwlock here, because the action must occur.
1301 The rarity and short potential lock duration makes this "OK"
1303 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1305 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1306 if ((*i)->record_enabled ()) {
1307 (*i)->monitor_input (false);
1312 RecordStateChanged (); /* emit signal */
1315 remove_pending_capture_state ();
1321 Session::step_back_from_record ()
1323 g_atomic_int_set (&_record_status, Enabled);
1325 if (Config->get_use_hardware_monitoring()) {
1326 /* Even though this can be called from RT context we are using
1327 a non-tentative rwlock here, because the action must occur.
1328 The rarity and short potential lock duration makes this "OK"
1330 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1332 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1333 if (auto_input && (*i)->record_enabled ()) {
1334 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1335 (*i)->monitor_input (false);
1342 Session::maybe_enable_record ()
1344 g_atomic_int_set (&_record_status, Enabled);
1346 /* XXX this save should really happen in another thread. its needed so that
1347 pending capture state can be recovered if we crash.
1350 save_state ("", true);
1352 if (_transport_speed) {
1357 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1358 RecordStateChanged (); /* EMIT SIGNAL */
1365 Session::audible_frame () const
1368 jack_nframes_t offset;
1371 /* the first of these two possible settings for "offset"
1372 mean that the audible frame is stationary until
1373 audio emerges from the latency compensation
1376 the second means that the audible frame is stationary
1377 until audio would emerge from a physical port
1378 in the absence of any plugin latency compensation
1381 offset = _worst_output_latency;
1383 if (offset > current_block_size) {
1384 offset -= current_block_size;
1386 /* XXX is this correct? if we have no external
1387 physical connections and everything is internal
1388 then surely this is zero? still, how
1389 likely is that anyway?
1391 offset = current_block_size;
1394 if (synced_to_jack()) {
1395 tf = _engine.transport_frame();
1397 tf = _transport_frame;
1400 if (_transport_speed == 0) {
1410 if (!non_realtime_work_pending()) {
1414 /* take latency into account */
1423 Session::set_frame_rate (jack_nframes_t frames_per_second)
1425 /** \fn void Session::set_frame_size(jack_nframes_t)
1426 the AudioEngine object that calls this guarantees
1427 that it will not be called while we are also in
1428 ::process(). Its fine to do things that block
1432 _current_frame_rate = frames_per_second;
1433 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1435 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1437 // XXX we need some equivalent to this, somehow
1438 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1442 /* XXX need to reset/reinstantiate all LADSPA plugins */
1446 Session::set_block_size (jack_nframes_t nframes)
1448 /* the AudioEngine guarantees
1449 that it will not be called while we are also in
1450 ::process(). It is therefore fine to do things that block
1455 Glib::RWLock::ReaderLock lm (route_lock);
1456 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1457 vector<Sample*>::iterator i;
1460 current_block_size = nframes;
1462 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1466 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1470 _passthru_buffers.clear ();
1471 _silent_buffers.clear ();
1473 ensure_passthru_buffers (np);
1475 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1479 #ifdef NO_POSIX_MEMALIGN
1480 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1482 posix_memalign((void **)&buf,16,current_block_size * 4);
1486 memset (*i, 0, sizeof (Sample) * current_block_size);
1490 if (_gain_automation_buffer) {
1491 delete [] _gain_automation_buffer;
1493 _gain_automation_buffer = new gain_t[nframes];
1495 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1497 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1498 (*i)->set_block_size (nframes);
1501 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1502 (*i)->set_block_size (nframes);
1505 set_worst_io_latencies (false);
1510 Session::set_default_fade (float steepness, float fade_msecs)
1513 jack_nframes_t fade_frames;
1515 /* Don't allow fade of less 1 frame */
1517 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1524 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1528 default_fade_msecs = fade_msecs;
1529 default_fade_steepness = steepness;
1532 // jlc, WTF is this!
1533 Glib::RWLock::ReaderLock lm (route_lock);
1534 AudioRegion::set_default_fade (steepness, fade_frames);
1539 /* XXX have to do this at some point */
1540 /* foreach region using default fade, reset, then
1541 refill_all_diskstream_buffers ();
1546 struct RouteSorter {
1547 bool operator() (Route* r1, Route* r2) {
1548 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1550 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1553 if (r1->fed_by.empty()) {
1554 if (r2->fed_by.empty()) {
1555 /* no ardour-based connections inbound to either route. just use signal order */
1556 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1558 /* r2 has connections, r1 does not; run r1 early */
1562 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1569 trace_terminal (Route* r1, Route* rbase)
1573 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1574 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1578 /* make a copy of the existing list of routes that feed r1 */
1580 set<Route *> existing = r1->fed_by;
1582 /* for each route that feeds r1, recurse, marking it as feeding
1586 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1589 /* r2 is a route that feeds r1 which somehow feeds base. mark
1590 base as being fed by r2
1593 rbase->fed_by.insert (r2);
1597 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1601 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1605 /* now recurse, so that we can mark base as being fed by
1606 all routes that feed r2
1609 trace_terminal (r2, rbase);
1616 Session::resort_routes (void* src)
1618 /* don't do anything here with signals emitted
1619 by Routes while we are being destroyed.
1622 if (_state_of_the_state & Deletion) {
1626 /* Caller MUST hold the route_lock */
1628 RouteList::iterator i, j;
1630 for (i = routes.begin(); i != routes.end(); ++i) {
1632 (*i)->fed_by.clear ();
1634 for (j = routes.begin(); j != routes.end(); ++j) {
1636 /* although routes can feed themselves, it will
1637 cause an endless recursive descent if we
1638 detect it. so don't bother checking for
1646 if ((*j)->feeds (*i)) {
1647 (*i)->fed_by.insert (*j);
1652 for (i = routes.begin(); i != routes.end(); ++i) {
1653 trace_terminal (*i, *i);
1660 cerr << "finished route resort\n";
1662 for (i = routes.begin(); i != routes.end(); ++i) {
1663 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1671 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1674 char track_name[32];
1676 uint32_t channels_used = 0;
1678 uint32_t nphysical_in;
1679 uint32_t nphysical_out;
1681 /* count existing audio tracks */
1684 Glib::RWLock::ReaderLock lm (route_lock);
1685 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1686 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1687 if (!(*i)->hidden()) {
1689 channels_used += (*i)->n_inputs();
1695 /* check for duplicate route names, since we might have pre-existing
1696 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1697 save, close,restart,add new route - first named route is now
1702 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1703 if (route_by_name (track_name) == 0) {
1708 } while (n < (UINT_MAX-1));
1710 if (input_auto_connect & AutoConnectPhysical) {
1711 nphysical_in = n_physical_inputs;
1716 if (output_auto_connect & AutoConnectPhysical) {
1717 nphysical_out = n_physical_outputs;
1723 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1725 if (track->ensure_io (input_channels, output_channels, false, this)) {
1726 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1727 input_channels, output_channels)
1732 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1736 if (input_auto_connect & AutoConnectPhysical) {
1737 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1740 if (port.length() && track->connect_input (track->input (x), port, this)) {
1746 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1750 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1751 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1752 } else if (output_auto_connect & AutoConnectMaster) {
1754 port = _master_out->input (x%_master_out->n_inputs())->name();
1758 if (port.length() && track->connect_output (track->output (x), port, this)) {
1764 vector<string> cports;
1765 uint32_t ni = _control_out->n_inputs();
1767 for (n = 0; n < ni; ++n) {
1768 cports.push_back (_control_out->input(n)->name());
1771 track->set_control_outs (cports);
1774 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1778 track->set_remote_control_id (ntracks());
1781 catch (failed_constructor &err) {
1782 error << _("Session: could not create new audio track.") << endmsg;
1790 Session::new_audio_route (int input_channels, int output_channels)
1797 /* count existing audio busses */
1800 Glib::RWLock::ReaderLock lm (route_lock);
1801 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1802 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1803 if (!(*i)->hidden()) {
1811 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1812 if (route_by_name (bus_name) == 0) {
1817 } while (n < (UINT_MAX-1));
1820 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1822 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1823 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1824 input_channels, output_channels)
1828 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1832 if (input_auto_connect & AutoConnectPhysical) {
1833 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1836 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1841 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1845 if (output_auto_connect & AutoConnectPhysical) {
1846 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1847 } else if (output_auto_connect & AutoConnectMaster) {
1849 port = _master_out->input (x%_master_out->n_inputs())->name();
1853 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1859 vector<string> cports;
1860 uint32_t ni = _control_out->n_inputs();
1862 for (uint32_t n = 0; n < ni; ++n) {
1863 cports.push_back (_control_out->input(n)->name());
1865 bus->set_control_outs (cports);
1871 catch (failed_constructor &err) {
1872 error << _("Session: could not create new route.") << endmsg;
1880 Session::add_route (Route* route)
1883 Glib::RWLock::WriterLock lm (route_lock);
1884 routes.push_front (route);
1888 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1889 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1890 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1891 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1893 if (route->master()) {
1894 _master_out = route;
1897 if (route->control()) {
1898 _control_out = route;
1902 save_state (_current_snapshot_name);
1904 RouteAdded (route); /* EMIT SIGNAL */
1908 Session::add_diskstream (AudioDiskstream* dstream)
1910 /* need to do this in case we're rolling at the time, to prevent false underruns */
1911 dstream->do_refill(0, 0, 0);
1914 Glib::RWLock::WriterLock lm (diskstream_lock);
1915 audio_diskstreams.push_back (dstream);
1918 /* take a reference to the diskstream, preventing it from
1919 ever being deleted until the session itself goes away,
1920 or chooses to remove it for its own purposes.
1924 dstream->set_block_size (current_block_size);
1926 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1927 /* this will connect to future changes, and check the current length */
1928 diskstream_playlist_changed (dstream);
1930 dstream->prepare ();
1933 save_state (_current_snapshot_name);
1935 AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
1939 Session::remove_route (Route& route)
1942 Glib::RWLock::WriterLock lm (route_lock);
1943 routes.remove (&route);
1945 /* deleting the master out seems like a dumb
1946 idea, but its more of a UI policy issue
1950 if (&route == _master_out) {
1954 if (&route == _control_out) {
1957 /* cancel control outs for all routes */
1959 vector<string> empty;
1961 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1962 (*r)->set_control_outs (empty);
1966 update_route_solo_state ();
1970 AudioDiskstream* ds = 0;
1972 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1973 ds = &at->disk_stream();
1979 Glib::RWLock::WriterLock lm (diskstream_lock);
1980 audio_diskstreams.remove (ds);
1986 find_current_end ();
1988 update_latency_compensation (false, false);
1991 /* XXX should we disconnect from the Route's signals ? */
1993 save_state (_current_snapshot_name);
1999 Session::route_mute_changed (void* src)
2005 Session::route_solo_changed (void* src, Route* route)
2007 if (solo_update_disabled) {
2012 Glib::RWLock::ReaderLock lm (route_lock);
2015 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2017 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2019 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2023 /* don't mess with busses */
2025 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2031 /* don't mess with tracks */
2033 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2038 if ((*i) != route &&
2039 ((*i)->mix_group () == 0 ||
2040 (*i)->mix_group () != route->mix_group () ||
2041 !route->mix_group ()->is_active())) {
2043 if ((*i)->soloed()) {
2045 /* if its already soloed, and solo latching is enabled,
2046 then leave it as it is.
2049 if (_solo_latched) {
2056 solo_update_disabled = true;
2057 (*i)->set_solo (false, src);
2058 solo_update_disabled = false;
2062 bool something_soloed = false;
2063 bool same_thing_soloed = false;
2064 bool signal = false;
2066 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2067 if ((*i)->soloed()) {
2068 something_soloed = true;
2069 if (dynamic_cast<AudioTrack*>(*i)) {
2071 same_thing_soloed = true;
2076 same_thing_soloed = true;
2084 if (something_soloed != currently_soloing) {
2086 currently_soloing = something_soloed;
2089 modify_solo_mute (is_track, same_thing_soloed);
2092 SoloActive (currently_soloing);
2099 Session::set_solo_latched (bool yn)
2101 if (yn != _solo_latched) {
2104 ControlChanged (SoloLatch);
2109 Session::update_route_solo_state ()
2112 bool is_track = false;
2113 bool signal = false;
2115 /* caller must hold RouteLock */
2117 /* this is where we actually implement solo by changing
2118 the solo mute setting of each track.
2121 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2122 if ((*i)->soloed()) {
2124 if (dynamic_cast<AudioTrack*>(*i)) {
2131 if (mute != currently_soloing) {
2133 currently_soloing = mute;
2136 if (!is_track && !mute) {
2138 /* nothing is soloed */
2140 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2141 (*i)->set_solo_mute (false);
2151 modify_solo_mute (is_track, mute);
2154 SoloActive (currently_soloing);
2159 Session::modify_solo_mute (bool is_track, bool mute)
2161 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2165 /* only alter track solo mute */
2167 if (dynamic_cast<AudioTrack*>(*i)) {
2168 if ((*i)->soloed()) {
2169 (*i)->set_solo_mute (!mute);
2171 (*i)->set_solo_mute (mute);
2177 /* only alter bus solo mute */
2179 if (!dynamic_cast<AudioTrack*>(*i)) {
2181 if ((*i)->soloed()) {
2183 (*i)->set_solo_mute (false);
2187 /* don't mute master or control outs
2188 in response to another bus solo
2191 if ((*i) != _master_out &&
2192 (*i) != _control_out) {
2193 (*i)->set_solo_mute (mute);
2204 Session::catch_up_on_solo ()
2206 /* this is called after set_state() to catch the full solo
2207 state, which can't be correctly determined on a per-route
2208 basis, but needs the global overview that only the session
2211 Glib::RWLock::ReaderLock lm (route_lock);
2212 update_route_solo_state();
2216 Session::route_by_name (string name)
2218 Glib::RWLock::ReaderLock lm (route_lock);
2220 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2221 if ((*i)->name() == name) {
2230 Session::route_by_remote_id (uint32_t id)
2232 Glib::RWLock::ReaderLock lm (route_lock);
2234 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2235 if ((*i)->remote_control_id() == id) {
2244 Session::find_current_end ()
2246 if (_state_of_the_state & Loading) {
2250 jack_nframes_t max = get_maximum_extent ();
2252 if (max > end_location->end()) {
2253 end_location->set_end (max);
2255 DurationChanged(); /* EMIT SIGNAL */
2260 Session::get_maximum_extent () const
2262 jack_nframes_t max = 0;
2265 /* Don't take the diskstream lock. Caller must have other ways to
2269 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2270 Playlist* pl = (*i)->playlist();
2271 if ((me = pl->get_maximum_extent()) > max) {
2280 Session::diskstream_by_name (string name)
2282 Glib::RWLock::ReaderLock lm (diskstream_lock);
2284 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2285 if ((*i)->name() == name) {
2294 Session::diskstream_by_id (const PBD::ID& id)
2296 Glib::RWLock::ReaderLock lm (diskstream_lock);
2298 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2299 if ((*i)->id() == id) {
2307 /* AudioRegion management */
2310 Session::new_region_name (string old)
2312 string::size_type last_period;
2314 string::size_type len = old.length() + 64;
2317 if ((last_period = old.find_last_of ('.')) == string::npos) {
2319 /* no period present - add one explicitly */
2322 last_period = old.length() - 1;
2327 number = atoi (old.substr (last_period+1).c_str());
2331 while (number < (UINT_MAX-1)) {
2333 AudioRegionList::const_iterator i;
2338 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2341 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2342 if (i->second->name() == sbuf) {
2347 if (i == audio_regions.end()) {
2352 if (number != (UINT_MAX-1)) {
2356 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2361 Session::region_name (string& result, string base, bool newlevel) const
2368 Glib::Mutex::Lock lm (region_lock);
2370 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2378 /* XXX this is going to be slow. optimize me later */
2383 string::size_type pos;
2385 pos = base.find_last_of ('.');
2387 /* pos may be npos, but then we just use entire base */
2389 subbase = base.substr (0, pos);
2393 bool name_taken = true;
2396 Glib::Mutex::Lock lm (region_lock);
2398 for (int n = 1; n < 5000; ++n) {
2401 snprintf (buf, sizeof (buf), ".%d", n);
2406 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2407 if (i->second->name() == result) {
2420 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2428 Session::add_region (Region* region)
2430 AudioRegion* ar = 0;
2431 AudioRegion* oar = 0;
2435 Glib::Mutex::Lock lm (region_lock);
2437 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2439 AudioRegionList::iterator x;
2441 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2443 oar = dynamic_cast<AudioRegion*> (x->second);
2445 if (ar->region_list_equivalent (*oar)) {
2450 if (x == audio_regions.end()) {
2452 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2454 entry.first = region->id();
2457 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2468 fatal << _("programming error: ")
2469 << X_("unknown region type passed to Session::add_region()")
2476 /* mark dirty because something has changed even if we didn't
2477 add the region to the region list.
2483 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2484 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2485 AudioRegionAdded (ar); /* EMIT SIGNAL */
2490 Session::region_changed (Change what_changed, Region* region)
2492 if (what_changed & Region::HiddenChanged) {
2493 /* relay hidden changes */
2494 RegionHiddenChange (region);
2499 Session::region_renamed (Region* region)
2501 add_region (region);
2505 Session::remove_region (Region* region)
2507 AudioRegionList::iterator i;
2508 AudioRegion* ar = 0;
2509 bool removed = false;
2512 Glib::Mutex::Lock lm (region_lock);
2514 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2515 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2516 audio_regions.erase (i);
2522 fatal << _("programming error: ")
2523 << X_("unknown region type passed to Session::remove_region()")
2529 /* mark dirty because something has changed even if we didn't
2530 remove the region from the region list.
2536 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2541 Session::find_whole_file_parent (AudioRegion& child)
2543 AudioRegionList::iterator i;
2544 AudioRegion* region;
2545 Glib::Mutex::Lock lm (region_lock);
2547 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2551 if (region->whole_file()) {
2553 if (child.source_equivalent (*region)) {
2563 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2565 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2569 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2573 pl->get_region_list_equivalent_regions (region, result);
2578 Session::destroy_region (Region* region)
2580 AudioRegion* aregion;
2582 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2586 if (aregion->playlist()) {
2587 aregion->playlist()->destroy_region (region);
2590 vector<Source*> srcs;
2592 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2593 srcs.push_back (&aregion->source (n));
2596 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2598 if ((*i)->use_cnt() == 0) {
2599 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2601 (afs)->mark_for_remove ();
2611 Session::destroy_regions (list<Region*> regions)
2613 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2614 destroy_region (*i);
2620 Session::remove_last_capture ()
2624 Glib::RWLock::ReaderLock lm (diskstream_lock);
2626 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2627 list<Region*>& l = (*i)->last_capture_regions();
2630 r.insert (r.end(), l.begin(), l.end());
2635 destroy_regions (r);
2640 Session::remove_region_from_region_list (Region& r)
2646 /* Source Management */
2649 Session::add_audio_source (AudioSource* source)
2651 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2654 Glib::Mutex::Lock lm (audio_source_lock);
2655 entry.first = source->id();
2656 entry.second = source;
2657 audio_sources.insert (entry);
2660 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2663 SourceAdded (source); /* EMIT SIGNAL */
2667 Session::remove_source (Source* source)
2669 AudioSourceList::iterator i;
2672 Glib::Mutex::Lock lm (audio_source_lock);
2674 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2675 audio_sources.erase (i);
2679 if (!_state_of_the_state & InCleanup) {
2681 /* save state so we don't end up with a session file
2682 referring to non-existent sources.
2685 save_state (_current_snapshot_name);
2688 SourceRemoved(source); /* EMIT SIGNAL */
2692 Session::source_by_id (const PBD::ID& id)
2694 Glib::Mutex::Lock lm (audio_source_lock);
2695 AudioSourceList::iterator i;
2698 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2702 /* XXX search MIDI or other searches here */
2708 Session::peak_path_from_audio_path (string audio_path)
2710 /* XXX hardly bombproof! fix me */
2714 res = Glib::path_get_dirname (audio_path);
2715 res = Glib::path_get_dirname (res);
2717 res += peak_dir_name;
2719 res += PBD::basename_nosuffix (audio_path);
2726 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2729 string old_basename = PBD::basename_nosuffix (oldname);
2730 string new_legalized = legalize_for_path (newname);
2732 /* note: we know (or assume) the old path is already valid */
2736 /* destructive file sources have a name of the form:
2738 /path/to/Tnnnn-NAME(%[LR])?.wav
2740 the task here is to replace NAME with the new name.
2743 /* find last slash */
2747 string::size_type slash;
2748 string::size_type dash;
2750 if ((slash = path.find_last_of ('/')) == string::npos) {
2754 dir = path.substr (0, slash+1);
2756 /* '-' is not a legal character for the NAME part of the path */
2758 if ((dash = path.find_last_of ('-')) == string::npos) {
2762 prefix = path.substr (slash+1, dash-(slash+1));
2767 path += new_legalized;
2768 path += ".wav"; /* XXX gag me with a spoon */
2772 /* non-destructive file sources have a name of the form:
2774 /path/to/NAME-nnnnn(%[LR])?.wav
2776 the task here is to replace NAME with the new name.
2779 /* find last slash */
2783 string::size_type slash;
2784 string::size_type dash;
2786 if ((slash = path.find_last_of ('/')) == string::npos) {
2790 dir = path.substr (0, slash+1);
2792 /* '-' is not a legal character for the NAME part of the path */
2794 if ((dash = path.find_last_of ('-')) == string::npos) {
2798 suffix = path.substr (dash);
2801 path += new_legalized;
2809 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2813 char buf[PATH_MAX+1];
2814 const uint32_t limit = 10000;
2818 legalized = legalize_for_path (name);
2820 /* find a "version" of the file name that doesn't exist in
2821 any of the possible directories.
2824 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2826 vector<space_and_path>::iterator i;
2827 uint32_t existing = 0;
2829 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2834 spath += tape_dir_name;
2836 spath += sound_dir_name;
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2842 } else if (nchan == 2) {
2844 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2848 } else if (nchan < 26) {
2849 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2851 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2859 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2860 } else if (nchan == 2) {
2862 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2864 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2866 } else if (nchan < 26) {
2867 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2869 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2873 if (access (buf, F_OK) == 0) {
2878 if (existing == 0) {
2883 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2884 throw failed_constructor();
2888 /* we now have a unique name for the file, but figure out where to
2895 spath = tape_dir ();
2897 spath = discover_best_sound_dir ();
2900 string::size_type pos = foo.find_last_of ('/');
2902 if (pos == string::npos) {
2905 spath += foo.substr (pos + 1);
2912 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2914 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2916 /* this might throw failed_constructor(), which is OK */
2919 return new DestructiveFileSource (spath,
2920 Config->get_native_file_data_format(),
2921 Config->get_native_file_header_format(),
2924 return new SndFileSource (spath,
2925 Config->get_native_file_data_format(),
2926 Config->get_native_file_header_format(),
2931 /* Playlist management */
2934 Session::get_playlist (string name)
2938 if ((ret = playlist_by_name (name)) == 0) {
2939 ret = new AudioPlaylist (*this, name);
2946 Session::playlist_by_name (string name)
2948 Glib::Mutex::Lock lm (playlist_lock);
2949 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2950 if ((*i)->name() == name) {
2954 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2955 if ((*i)->name() == name) {
2963 Session::add_playlist (Playlist* playlist)
2965 if (playlist->hidden()) {
2970 Glib::Mutex::Lock lm (playlist_lock);
2971 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2972 playlists.insert (playlists.begin(), playlist);
2974 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2975 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2981 PlaylistAdded (playlist); /* EMIT SIGNAL */
2985 Session::track_playlist (Playlist* pl, bool inuse)
2987 PlaylistList::iterator x;
2990 Glib::Mutex::Lock lm (playlist_lock);
2993 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2995 unused_playlists.insert (pl);
2997 if ((x = playlists.find (pl)) != playlists.end()) {
2998 playlists.erase (x);
3003 //cerr << "shifting playlist to used: " << pl->name() << endl;
3005 playlists.insert (pl);
3007 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3008 unused_playlists.erase (x);
3015 Session::remove_playlist (Playlist* playlist)
3017 if (_state_of_the_state & Deletion) {
3022 Glib::Mutex::Lock lm (playlist_lock);
3023 // cerr << "removing playlist: " << playlist->name() << endl;
3025 PlaylistList::iterator i;
3027 i = find (playlists.begin(), playlists.end(), playlist);
3029 if (i != playlists.end()) {
3030 playlists.erase (i);
3033 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3034 if (i != unused_playlists.end()) {
3035 unused_playlists.erase (i);
3042 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3046 Session::set_audition (AudioRegion* r)
3048 pending_audition_region = r;
3049 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3050 schedule_butler_transport_work ();
3054 Session::non_realtime_set_audition ()
3056 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3057 auditioner->audition_current_playlist ();
3058 } else if (pending_audition_region) {
3059 auditioner->audition_region (*pending_audition_region);
3061 pending_audition_region = 0;
3062 AuditionActive (true); /* EMIT SIGNAL */
3066 Session::audition_playlist ()
3068 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3069 ev->set_ptr ((void*) 0xfeedface);
3074 Session::audition_region (AudioRegion& r)
3076 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3082 Session::cancel_audition ()
3084 if (auditioner->active()) {
3085 auditioner->cancel_audition ();
3086 AuditionActive (false); /* EMIT SIGNAL */
3091 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3093 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3097 Session::remove_empty_sounds ()
3100 PathScanner scanner;
3105 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3107 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3109 if (AudioFileSource::is_empty (*(*i))) {
3111 unlink ((*i)->c_str());
3113 string peak_path = peak_path_from_audio_path (**i);
3114 unlink (peak_path.c_str());
3120 delete possible_audiofiles;
3124 Session::is_auditioning () const
3126 /* can be called before we have an auditioner object */
3128 return auditioner->active();
3135 Session::set_all_solo (bool yn)
3138 Glib::RWLock::ReaderLock lm (route_lock);
3140 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3141 if (!(*i)->hidden()) {
3142 (*i)->set_solo (yn, this);
3151 Session::set_all_mute (bool yn)
3154 Glib::RWLock::ReaderLock lm (route_lock);
3156 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3157 if (!(*i)->hidden()) {
3158 (*i)->set_mute (yn, this);
3167 Session::n_audio_diskstreams () const
3169 Glib::RWLock::ReaderLock lm (diskstream_lock);
3172 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3173 if (!(*i)->hidden()) {
3181 Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
3183 Glib::RWLock::ReaderLock lm (diskstream_lock);
3184 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3185 if (!(*i)->hidden()) {
3192 Session::graph_reordered ()
3194 /* don't do this stuff if we are setting up connections
3195 from a set_state() call.
3198 if (_state_of_the_state & InitialConnecting) {
3202 Glib::RWLock::WriterLock lm1 (route_lock);
3203 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3207 /* force all diskstreams to update their capture offset values to
3208 reflect any changes in latencies within the graph.
3211 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3212 (*i)->set_capture_offset ();
3217 Session::record_disenable_all ()
3219 record_enable_change_all (false);
3223 Session::record_enable_all ()
3225 record_enable_change_all (true);
3229 Session::record_enable_change_all (bool yn)
3231 Glib::RWLock::ReaderLock lm1 (route_lock);
3233 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3236 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3237 at->set_record_enable (yn, this);
3241 /* since we don't keep rec-enable state, don't mark session dirty */
3245 Session::add_redirect (Redirect* redirect)
3249 PortInsert* port_insert;
3250 PluginInsert* plugin_insert;
3252 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3253 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3254 _port_inserts.insert (_port_inserts.begin(), port_insert);
3255 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3256 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3258 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3261 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3262 _sends.insert (_sends.begin(), send);
3264 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3268 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3274 Session::remove_redirect (Redirect* redirect)
3278 PortInsert* port_insert;
3279 PluginInsert* plugin_insert;
3281 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3282 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3283 _port_inserts.remove (port_insert);
3284 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3285 _plugin_inserts.remove (plugin_insert);
3287 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3290 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3291 _sends.remove (send);
3293 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3301 Session::available_capture_duration ()
3303 const double scale = 4096.0 / sizeof (Sample);
3305 if (_total_free_4k_blocks * scale > (double) max_frames) {
3309 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3313 Session::add_connection (ARDOUR::Connection* connection)
3316 Glib::Mutex::Lock guard (connection_lock);
3317 _connections.push_back (connection);
3320 ConnectionAdded (connection); /* EMIT SIGNAL */
3326 Session::remove_connection (ARDOUR::Connection* connection)
3328 bool removed = false;
3331 Glib::Mutex::Lock guard (connection_lock);
3332 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3334 if (i != _connections.end()) {
3335 _connections.erase (i);
3341 ConnectionRemoved (connection); /* EMIT SIGNAL */
3347 ARDOUR::Connection *
3348 Session::connection_by_name (string name) const
3350 Glib::Mutex::Lock lm (connection_lock);
3352 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3353 if ((*i)->name() == name) {
3362 Session::set_edit_mode (EditMode mode)
3367 Glib::Mutex::Lock lm (playlist_lock);
3369 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3370 (*i)->set_edit_mode (mode);
3375 ControlChanged (EditingMode); /* EMIT SIGNAL */
3379 Session::tempo_map_changed (Change ignored)
3386 Session::ensure_passthru_buffers (uint32_t howmany)
3388 while (howmany > _passthru_buffers.size()) {
3390 #ifdef NO_POSIX_MEMALIGN
3391 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3393 posix_memalign((void **)&p,16,current_block_size * 4);
3395 _passthru_buffers.push_back (p);
3399 #ifdef NO_POSIX_MEMALIGN
3400 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3402 posix_memalign((void **)&p,16,current_block_size * 4);
3404 memset (p, 0, sizeof (Sample) * current_block_size);
3405 _silent_buffers.push_back (p);
3409 #ifdef NO_POSIX_MEMALIGN
3410 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3412 posix_memalign((void **)&p,16,current_block_size * 4);
3414 memset (p, 0, sizeof (Sample) * current_block_size);
3415 _send_buffers.push_back (p);
3418 allocate_pan_automation_buffers (current_block_size, howmany, false);
3422 Session::next_send_name ()
3425 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3430 Session::next_insert_name ()
3433 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3437 /* Named Selection management */
3440 Session::named_selection_by_name (string name)
3442 Glib::Mutex::Lock lm (named_selection_lock);
3443 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3444 if ((*i)->name == name) {
3452 Session::add_named_selection (NamedSelection* named_selection)
3455 Glib::Mutex::Lock lm (named_selection_lock);
3456 named_selections.insert (named_selections.begin(), named_selection);
3461 NamedSelectionAdded (); /* EMIT SIGNAL */
3465 Session::remove_named_selection (NamedSelection* named_selection)
3467 bool removed = false;
3470 Glib::Mutex::Lock lm (named_selection_lock);
3472 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3474 if (i != named_selections.end()) {
3476 named_selections.erase (i);
3483 NamedSelectionRemoved (); /* EMIT SIGNAL */
3488 Session::reset_native_file_format ()
3490 // jlc - WHY take routelock?
3491 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3492 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3494 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3495 (*i)->reset_write_sources (false);
3500 Session::route_name_unique (string n) const
3502 Glib::RWLock::ReaderLock lm (route_lock);
3504 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3505 if ((*i)->name() == n) {
3514 Session::cleanup_audio_file_source (AudioFileSource& fs)
3516 return fs.move_to_trash (dead_sound_dir_name);
3520 Session::n_playlists () const
3522 Glib::Mutex::Lock lm (playlist_lock);
3523 return playlists.size();
3527 Session::set_solo_model (SoloModel sm)
3529 if (sm != _solo_model) {
3531 ControlChanged (SoloingModel);
3537 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3539 if (!force && howmany <= _npan_buffers) {
3543 if (_pan_automation_buffer) {
3545 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3546 delete [] _pan_automation_buffer[i];
3549 delete [] _pan_automation_buffer;
3552 _pan_automation_buffer = new pan_t*[howmany];
3554 for (uint32_t i = 0; i < howmany; ++i) {
3555 _pan_automation_buffer[i] = new pan_t[nframes];
3558 _npan_buffers = howmany;
3562 Session::freeze (InterThreadInfo& itt)
3564 Glib::RWLock::ReaderLock lm (route_lock);
3566 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3570 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3571 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3582 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3583 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3587 AudioFileSource* fsource;
3589 char buf[PATH_MAX+1];
3592 jack_nframes_t position;
3593 jack_nframes_t this_chunk;
3594 jack_nframes_t to_do;
3595 vector<Sample*> buffers;
3598 // any bigger than this seems to cause stack overflows in called functions
3599 const jack_nframes_t chunk_size = (128 * 1024)/4;
3601 g_atomic_int_set (&processing_prohibited, 1);
3603 /* call tree *MUST* hold route_lock */
3605 if ((playlist = track.disk_stream().playlist()) == 0) {
3609 /* external redirects will be a problem */
3611 if (track.has_external_redirects()) {
3615 nchans = track.disk_stream().n_channels();
3617 dir = discover_best_sound_dir ();
3619 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3621 for (x = 0; x < 99999; ++x) {
3622 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3623 if (access (buf, F_OK) != 0) {
3629 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3634 fsource = new SndFileSource (buf,
3635 Config->get_native_file_data_format(),
3636 Config->get_native_file_header_format(),
3641 catch (failed_constructor& err) {
3642 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3646 srcs.push_back(fsource);
3649 /* XXX need to flush all redirects */
3654 /* create a set of reasonably-sized buffers */
3656 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3658 #ifdef NO_POSIX_MEMALIGN
3659 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3661 posix_memalign((void **)&b,16,chunk_size * 4);
3663 buffers.push_back (b);
3666 workbuf = new char[chunk_size * 4];
3668 while (to_do && !itt.cancel) {
3670 this_chunk = min (to_do, chunk_size);
3672 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3677 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3678 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3681 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3687 start += this_chunk;
3688 to_do -= this_chunk;
3690 itt.progress = (float) (1.0 - ((double) to_do / len));
3699 xnow = localtime (&now);
3701 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3702 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3704 afs->update_header (position, *xnow, now);
3708 /* build peakfile for new source */
3710 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3711 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3713 afs->build_peaks ();
3722 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3723 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3725 afs->mark_for_remove ();
3731 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3739 g_atomic_int_set (&processing_prohibited, 0);
3747 Session::get_silent_buffers (uint32_t howmany)
3749 for (uint32_t i = 0; i < howmany; ++i) {
3750 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3752 return _silent_buffers;
3756 Session::ntracks () const
3759 Glib::RWLock::ReaderLock lm (route_lock);
3761 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3762 if (dynamic_cast<AudioTrack*> (*i)) {
3771 Session::nbusses () const
3774 Glib::RWLock::ReaderLock lm (route_lock);
3776 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3777 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3786 Session::set_layer_model (LayerModel lm)
3788 if (lm != layer_model) {
3791 ControlChanged (LayeringModel);
3796 Session::set_xfade_model (CrossfadeModel xm)
3798 if (xm != xfade_model) {
3801 ControlChanged (CrossfadingModel);