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 <pbd/error.h>
36 #include <pbd/lockmonitor.h>
37 #include <pbd/pathscanner.h>
38 #include <pbd/stl_delete.h>
39 #include <pbd/basename.h>
40 #include <pbd/dirname.h>
42 #include <ardour/audioengine.h>
43 #include <ardour/configuration.h>
44 #include <ardour/session.h>
45 #include <ardour/diskstream.h>
46 #include <ardour/utils.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/audioregion.h>
49 #include <ardour/source.h>
50 #include <ardour/filesource.h>
51 #include <ardour/destructive_filesource.h>
52 #include <ardour/sndfilesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/timestamps.h>
72 using namespace ARDOUR;
73 //using namespace sigc;
75 const char* Session::_template_suffix = X_(".template");
76 const char* Session::_statefile_suffix = X_(".ardour");
77 const char* Session::_pending_suffix = X_(".pending");
78 const char* Session::sound_dir_name = X_("sounds");
79 const char* Session::tape_dir_name = X_("tapes");
80 const char* Session::peak_dir_name = X_("peaks");
81 const char* Session::dead_sound_dir_name = X_("dead_sounds");
83 Session::compute_peak_t Session::compute_peak = 0;
84 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
85 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
86 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
88 sigc::signal<int> Session::AskAboutPendingState;
91 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
98 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
99 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
105 /* check to see if it exists, and what it is */
107 if (stat (str.c_str(), &statbuf)) {
108 if (errno == ENOENT) {
111 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
119 /* it exists, so it must either be the name
120 of the directory, or the name of the statefile
124 if (S_ISDIR (statbuf.st_mode)) {
126 string::size_type slash = str.find_last_of ('/');
128 if (slash == string::npos) {
130 /* a subdirectory of cwd, so statefile should be ... */
136 tmp += _statefile_suffix;
140 if (stat (tmp.c_str(), &statbuf)) {
141 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
151 /* some directory someplace in the filesystem.
152 the snapshot name is the directory name
157 snapshot = str.substr (slash+1);
161 } else if (S_ISREG (statbuf.st_mode)) {
163 string::size_type slash = str.find_last_of ('/');
164 string::size_type suffix;
166 /* remove the suffix */
168 if (slash != string::npos) {
169 snapshot = str.substr (slash+1);
174 suffix = snapshot.find (_statefile_suffix);
176 if (suffix == string::npos) {
177 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
183 snapshot = snapshot.substr (0, suffix);
185 if (slash == string::npos) {
187 /* we must be in the directory where the
188 statefile lives. get it using cwd().
191 char cwd[PATH_MAX+1];
193 if (getcwd (cwd, sizeof (cwd)) == 0) {
194 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
203 /* full path to the statefile */
205 path = str.substr (0, slash);
210 /* what type of file is it? */
211 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
217 /* its the name of a new directory. get the name
221 string::size_type slash = str.find_last_of ('/');
223 if (slash == string::npos) {
225 /* no slash, just use the name, but clean it up */
227 path = legalize_for_path (str);
233 snapshot = str.substr (slash+1);
240 Session::Session (AudioEngine &eng,
242 string snapshot_name,
243 string* mix_template)
246 _mmc_port (default_mmc_port),
247 _mtc_port (default_mtc_port),
248 _midi_port (default_midi_port),
249 pending_events (2048),
250 midi_requests (128), // the size of this should match the midi request pool size
255 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
257 n_physical_outputs = _engine.n_physical_outputs();
258 n_physical_inputs = _engine.n_physical_inputs();
260 first_stage_init (fullpath, snapshot_name);
262 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
263 throw failed_constructor ();
266 if (second_stage_init (new_session)) {
267 throw failed_constructor ();
270 store_recent_sessions(_name, _path);
272 bool was_dirty = dirty();
274 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
277 DirtyChanged (); /* EMIT SIGNAL */
281 Session::Session (AudioEngine &eng,
283 string snapshot_name,
284 AutoConnectOption input_ac,
285 AutoConnectOption output_ac,
286 uint32_t control_out_channels,
287 uint32_t master_out_channels,
288 uint32_t requested_physical_in,
289 uint32_t requested_physical_out,
290 jack_nframes_t initial_length)
293 _mmc_port (default_mmc_port),
294 _mtc_port (default_mtc_port),
295 _midi_port (default_midi_port),
296 pending_events (2048),
303 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
305 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
306 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
308 first_stage_init (fullpath, snapshot_name);
310 if (create (new_session, 0, initial_length)) {
311 throw failed_constructor ();
314 if (control_out_channels) {
316 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
321 if (master_out_channels) {
323 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
327 /* prohibit auto-connect to master, because there isn't one */
328 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
331 input_auto_connect = input_ac;
332 output_auto_connect = output_ac;
334 if (second_stage_init (new_session)) {
335 throw failed_constructor ();
338 store_recent_sessions(_name, _path);
340 bool was_dirty = dirty ();
342 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
345 DirtyChanged (); /* EMIT SIGNAL */
351 /* if we got to here, leaving pending capture state around
355 remove_pending_capture_state ();
357 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
358 _engine.remove_session ();
360 going_away (); /* EMIT SIGNAL */
362 terminate_butler_thread ();
363 terminate_midi_thread ();
364 terminate_feedback ();
366 if (click_data && click_data != default_click) {
367 delete [] click_data;
370 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
371 delete [] click_emphasis_data;
385 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
389 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
393 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
397 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
398 delete [] (i->second);
401 #undef TRACK_DESTRUCTION
402 #ifdef TRACK_DESTRUCTION
403 cerr << "delete named selections\n";
404 #endif /* TRACK_DESTRUCTION */
405 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
406 NamedSelectionList::iterator tmp;
415 #ifdef TRACK_DESTRUCTION
416 cerr << "delete playlists\n";
417 #endif /* TRACK_DESTRUCTION */
418 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
419 PlaylistList::iterator tmp;
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete audio regions\n";
431 #endif /* TRACK_DESTRUCTION */
432 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
433 AudioRegionList::iterator tmp;
443 #ifdef TRACK_DESTRUCTION
444 cerr << "delete routes\n";
445 #endif /* TRACK_DESTRUCTION */
446 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
447 RouteList::iterator tmp;
454 #ifdef TRACK_DESTRUCTION
455 cerr << "delete diskstreams\n";
456 #endif /* TRACK_DESTRUCTION */
457 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
458 DiskStreamList::iterator tmp;
468 #ifdef TRACK_DESTRUCTION
469 cerr << "delete sources\n";
470 #endif /* TRACK_DESTRUCTION */
471 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
472 SourceList::iterator tmp;
482 #ifdef TRACK_DESTRUCTION
483 cerr << "delete mix groups\n";
484 #endif /* TRACK_DESTRUCTION */
485 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
486 list<RouteGroup*>::iterator tmp;
496 #ifdef TRACK_DESTRUCTION
497 cerr << "delete edit groups\n";
498 #endif /* TRACK_DESTRUCTION */
499 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
500 list<RouteGroup*>::iterator tmp;
510 #ifdef TRACK_DESTRUCTION
511 cerr << "delete connections\n";
512 #endif /* TRACK_DESTRUCTION */
513 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
514 ConnectionList::iterator tmp;
524 if (butler_mixdown_buffer) {
525 delete [] butler_mixdown_buffer;
528 if (butler_gain_buffer) {
529 delete [] butler_gain_buffer;
532 Crossfade::set_buffer_size (0);
544 Session::set_worst_io_latencies (bool take_lock)
546 _worst_output_latency = 0;
547 _worst_input_latency = 0;
549 if (!_engine.connected()) {
554 route_lock.read_lock ();
557 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
558 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
559 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
563 route_lock.unlock ();
568 Session::when_engine_running ()
570 string first_physical_output;
572 /* we don't want to run execute this again */
574 first_time_running.disconnect ();
576 set_block_size (_engine.frames_per_cycle());
577 set_frame_rate (_engine.frame_rate());
579 /* every time we reconnect, recompute worst case output latencies */
581 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
583 if (synced_to_jack()) {
584 _engine.transport_stop ();
587 if (Config->get_jack_time_master()) {
588 _engine.transport_locate (_transport_frame);
596 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
598 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
600 /* existing state for Click */
602 if (_click_io->set_state (*child->children().front()) == 0) {
604 _clicking = click_requested;
608 error << _("could not setup Click I/O") << endmsg;
614 /* default state for Click */
616 first_physical_output = _engine.get_nth_physical_output (0);
618 if (first_physical_output.length()) {
619 if (_click_io->add_output_port (first_physical_output, this)) {
620 // relax, even though its an error
622 _clicking = click_requested;
628 catch (failed_constructor& err) {
629 error << _("cannot setup Click I/O") << endmsg;
632 set_worst_io_latencies (true);
635 ControlChanged (Clicking); /* EMIT SIGNAL */
638 if (auditioner == 0) {
640 /* we delay creating the auditioner till now because
641 it makes its own connections to ports named
642 in the ARDOUR_RC config file. the engine has
643 to be running for this to work.
647 auditioner = new Auditioner (*this);
650 catch (failed_constructor& err) {
651 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
655 /* Create a set of Connection objects that map
656 to the physical outputs currently available
661 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
663 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
665 Connection* c = new OutputConnection (buf, true);
668 c->add_connection (0, _engine.get_nth_physical_output (np));
673 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
675 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
677 Connection* c = new InputConnection (buf, true);
680 c->add_connection (0, _engine.get_nth_physical_input (np));
687 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
689 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
691 Connection* c = new OutputConnection (buf, true);
695 c->add_connection (0, _engine.get_nth_physical_output (np));
696 c->add_connection (1, _engine.get_nth_physical_output (np+1));
701 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
703 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
705 Connection* c = new InputConnection (buf, true);
709 c->add_connection (0, _engine.get_nth_physical_input (np));
710 c->add_connection (1, _engine.get_nth_physical_input (np+1));
719 /* create master/control ports */
724 /* force the master to ignore any later call to this */
726 if (_master_out->pending_state_node) {
727 _master_out->ports_became_legal();
730 /* no panner resets till we are through */
732 _master_out->defer_pan_reset ();
734 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
735 if (_master_out->add_input_port ("", this)) {
736 error << _("cannot setup master inputs")
742 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
743 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
744 error << _("cannot setup master outputs")
751 _master_out->allow_pan_reset ();
755 Connection* c = new OutputConnection (_("Master Out"), true);
757 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
759 c->add_connection ((int) n, _master_out->input(n)->name());
766 /* catch up on send+insert cnts */
770 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
773 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
774 if (id > insert_cnt) {
782 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
785 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
792 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
794 /* hook us up to the engine */
796 _engine.set_session (this);
798 _state_of_the_state = Clean;
800 DirtyChanged (); /* EMIT SIGNAL */
804 Session::hookup_io ()
806 /* stop graph reordering notifications from
807 causing resorts, etc.
810 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
812 /* Tell all IO objects to create their ports */
819 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
820 if (_control_out->add_input_port ("", this)) {
821 error << _("cannot setup control inputs")
827 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
828 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
829 error << _("cannot set up master outputs")
837 /* Tell all IO objects to connect themselves together */
839 IO::enable_connecting ();
841 /* Now reset all panners */
843 IO::reset_panners ();
845 /* Anyone who cares about input state, wake up and do something */
847 IOConnectionsComplete (); /* EMIT SIGNAL */
849 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
851 /* now handle the whole enchilada as if it was one
857 /* update mixer solo state */
863 Session::playlist_length_changed (Playlist* pl)
865 /* we can't just increase end_location->end() if pl->get_maximum_extent()
866 if larger. if the playlist used to be the longest playlist,
867 and its now shorter, we have to decrease end_location->end(). hence,
868 we have to iterate over all diskstreams and check the
869 playlists currently in use.
875 Session::diskstream_playlist_changed (DiskStream* dstream)
879 if ((playlist = dstream->playlist()) != 0) {
880 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
883 /* see comment in playlist_length_changed () */
888 Session::record_enabling_legal () const
890 /* this used to be in here, but survey says.... we don't need to restrict it */
891 // if (record_status() == Recording) {
902 Session::set_auto_play (bool yn)
904 if (auto_play != yn) {
907 ControlChanged (AutoPlay);
912 Session::set_auto_return (bool yn)
914 if (auto_return != yn) {
917 ControlChanged (AutoReturn);
922 Session::set_crossfades_active (bool yn)
924 if (crossfades_active != yn) {
925 crossfades_active = yn;
927 ControlChanged (CrossFadesActive);
932 Session::set_do_not_record_plugins (bool yn)
934 if (do_not_record_plugins != yn) {
935 do_not_record_plugins = yn;
937 ControlChanged (RecordingPlugins);
942 Session::set_auto_input (bool yn)
944 if (auto_input != yn) {
947 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
948 /* auto-input only makes a difference if we're rolling */
950 /* Even though this can called from RT context we are using
951 a non-tentative rwlock here, because the action must occur.
952 The rarity and short potential lock duration makes this "OK"
954 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
955 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
956 if ((*i)->record_enabled ()) {
957 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
958 (*i)->monitor_input (!auto_input);
964 ControlChanged (AutoInput);
969 Session::reset_input_monitor_state ()
971 if (transport_rolling()) {
972 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
973 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
974 if ((*i)->record_enabled ()) {
975 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
976 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
980 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
981 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
982 if ((*i)->record_enabled ()) {
983 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
984 (*i)->monitor_input (Config->get_use_hardware_monitoring());
992 Session::set_input_auto_connect (bool yn)
995 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
997 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1003 Session::get_input_auto_connect () const
1005 return (input_auto_connect & AutoConnectPhysical);
1009 Session::set_output_auto_connect (AutoConnectOption aco)
1011 output_auto_connect = aco;
1016 Session::auto_punch_start_changed (Location* location)
1018 replace_event (Event::PunchIn, location->start());
1020 if (get_record_enabled() && get_punch_in()) {
1021 /* capture start has been changed, so save new pending state */
1022 save_state ("", true);
1027 Session::auto_punch_end_changed (Location* location)
1029 jack_nframes_t when_to_stop = location->end();
1030 // when_to_stop += _worst_output_latency + _worst_input_latency;
1031 replace_event (Event::PunchOut, when_to_stop);
1035 Session::auto_punch_changed (Location* location)
1037 jack_nframes_t when_to_stop = location->end();
1039 replace_event (Event::PunchIn, location->start());
1040 //when_to_stop += _worst_output_latency + _worst_input_latency;
1041 replace_event (Event::PunchOut, when_to_stop);
1045 Session::auto_loop_changed (Location* location)
1047 replace_event (Event::AutoLoop, location->end(), location->start());
1049 if (transport_rolling() && get_auto_loop()) {
1051 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1053 if (_transport_frame > location->end()) {
1054 // relocate to beginning of loop
1055 clear_events (Event::LocateRoll);
1057 request_locate (location->start(), true);
1060 else if (seamless_loop && !loop_changing) {
1062 // schedule a locate-roll to refill the diskstreams at the
1063 // previous loop end
1064 loop_changing = true;
1066 if (location->end() > last_loopend) {
1067 clear_events (Event::LocateRoll);
1068 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1075 last_loopend = location->end();
1080 Session::set_auto_punch_location (Location* location)
1084 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1085 auto_punch_start_changed_connection.disconnect();
1086 auto_punch_end_changed_connection.disconnect();
1087 auto_punch_changed_connection.disconnect();
1088 existing->set_auto_punch (false, this);
1089 remove_event (existing->start(), Event::PunchIn);
1090 clear_events (Event::PunchOut);
1091 auto_punch_location_changed (0);
1096 if (location == 0) {
1100 if (location->end() <= location->start()) {
1101 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1105 auto_punch_start_changed_connection.disconnect();
1106 auto_punch_end_changed_connection.disconnect();
1107 auto_punch_changed_connection.disconnect();
1109 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1110 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1111 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1113 location->set_auto_punch (true, this);
1114 auto_punch_location_changed (location);
1118 Session::set_punch_in (bool yn)
1120 if (punch_in == yn) {
1126 if ((location = _locations.auto_punch_location()) != 0) {
1127 if ((punch_in = yn) == true) {
1128 replace_event (Event::PunchIn, location->start());
1130 remove_event (location->start(), Event::PunchIn);
1135 ControlChanged (PunchIn); /* EMIT SIGNAL */
1139 Session::set_punch_out (bool yn)
1141 if (punch_out == yn) {
1147 if ((location = _locations.auto_punch_location()) != 0) {
1148 if ((punch_out = yn) == true) {
1149 replace_event (Event::PunchOut, location->end());
1151 clear_events (Event::PunchOut);
1156 ControlChanged (PunchOut); /* EMIT SIGNAL */
1160 Session::set_auto_loop_location (Location* location)
1164 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1165 auto_loop_start_changed_connection.disconnect();
1166 auto_loop_end_changed_connection.disconnect();
1167 auto_loop_changed_connection.disconnect();
1168 existing->set_auto_loop (false, this);
1169 remove_event (existing->end(), Event::AutoLoop);
1170 auto_loop_location_changed (0);
1175 if (location == 0) {
1179 if (location->end() <= location->start()) {
1180 error << _("Session: you can't use a mark for auto loop") << endmsg;
1184 last_loopend = location->end();
1186 auto_loop_start_changed_connection.disconnect();
1187 auto_loop_end_changed_connection.disconnect();
1188 auto_loop_changed_connection.disconnect();
1190 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1191 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1192 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1194 location->set_auto_loop (true, this);
1195 auto_loop_location_changed (location);
1199 Session::locations_added (Location* ignored)
1205 Session::locations_changed ()
1207 _locations.apply (*this, &Session::handle_locations_changed);
1211 Session::handle_locations_changed (Locations::LocationList& locations)
1213 Locations::LocationList::iterator i;
1215 bool set_loop = false;
1216 bool set_punch = false;
1218 for (i = locations.begin(); i != locations.end(); ++i) {
1222 if (location->is_auto_punch()) {
1223 set_auto_punch_location (location);
1226 if (location->is_auto_loop()) {
1227 set_auto_loop_location (location);
1234 set_auto_loop_location (0);
1237 set_auto_punch_location (0);
1244 Session::enable_record ()
1246 /* XXX really atomic compare+swap here */
1247 if (atomic_read (&_record_status) != Recording) {
1248 atomic_set (&_record_status, Recording);
1249 _last_record_location = _transport_frame;
1250 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1252 if (Config->get_use_hardware_monitoring() && auto_input) {
1253 /* Even though this can be called from RT context we are using
1254 a non-tentative rwlock here, because the action must occur.
1255 The rarity and short potential lock duration makes this "OK"
1257 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1259 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1260 if ((*i)->record_enabled ()) {
1261 (*i)->monitor_input (true);
1266 RecordStateChanged ();
1271 Session::disable_record (bool rt_context, bool force)
1275 if ((rs = (RecordState) atomic_read (&_record_status)) != Disabled) {
1277 if (!Config->get_latched_record_enable () || force) {
1278 atomic_set (&_record_status, Disabled);
1280 if (rs == Recording) {
1281 atomic_set (&_record_status, Enabled);
1285 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1287 if (Config->get_use_hardware_monitoring() && auto_input) {
1288 /* Even though this can be called from RT context we are using
1289 a non-tentative rwlock here, because the action must occur.
1290 The rarity and short potential lock duration makes this "OK"
1292 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1294 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1295 if ((*i)->record_enabled ()) {
1296 (*i)->monitor_input (false);
1301 RecordStateChanged (); /* emit signal */
1304 remove_pending_capture_state ();
1310 Session::step_back_from_record ()
1312 atomic_set (&_record_status, Enabled);
1314 if (Config->get_use_hardware_monitoring()) {
1315 /* Even though this can be called from RT context we are using
1316 a non-tentative rwlock here, because the action must occur.
1317 The rarity and short potential lock duration makes this "OK"
1319 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1321 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1322 if (auto_input && (*i)->record_enabled ()) {
1323 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1324 (*i)->monitor_input (false);
1331 Session::maybe_enable_record ()
1333 atomic_set (&_record_status, Enabled);
1335 /* XXX this save should really happen in another thread. its needed so that
1336 pending capture state can be recovered if we crash.
1339 save_state ("", true);
1341 if (_transport_speed) {
1346 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1347 RecordStateChanged (); /* EMIT SIGNAL */
1354 Session::audible_frame () const
1357 jack_nframes_t offset;
1360 /* the first of these two possible settings for "offset"
1361 mean that the audible frame is stationary until
1362 audio emerges from the latency compensation
1365 the second means that the audible frame is stationary
1366 until audio would emerge from a physical port
1367 in the absence of any plugin latency compensation
1370 offset = _worst_output_latency;
1372 if (offset > current_block_size) {
1373 offset -= current_block_size;
1375 /* XXX is this correct? if we have no external
1376 physical connections and everything is internal
1377 then surely this is zero? still, how
1378 likely is that anyway?
1380 offset = current_block_size;
1383 if (synced_to_jack()) {
1384 tf = _engine.transport_frame();
1386 tf = _transport_frame;
1389 if (_transport_speed == 0) {
1399 if (!non_realtime_work_pending()) {
1403 /* take latency into account */
1412 Session::set_frame_rate (jack_nframes_t frames_per_second)
1414 /** \fn void Session::set_frame_size(jack_nframes_t)
1415 the AudioEngine object that calls this guarantees
1416 that it will not be called while we are also in
1417 ::process(). Its fine to do things that block
1421 _current_frame_rate = frames_per_second;
1422 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1424 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1428 /* XXX need to reset/reinstantiate all LADSPA plugins */
1432 Session::set_block_size (jack_nframes_t nframes)
1434 /* the AudioEngine guarantees
1435 that it will not be called while we are also in
1436 ::process(). It is therefore fine to do things that block
1441 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1442 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1443 vector<Sample*>::iterator i;
1446 current_block_size = nframes;
1448 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1452 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1456 _passthru_buffers.clear ();
1457 _silent_buffers.clear ();
1459 ensure_passthru_buffers (np);
1461 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1465 #ifdef NO_POSIX_MEMALIGN
1466 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1468 posix_memalign((void **)&buf,16,current_block_size * 4);
1472 memset (*i, 0, sizeof (Sample) * current_block_size);
1476 if (_gain_automation_buffer) {
1477 delete [] _gain_automation_buffer;
1479 _gain_automation_buffer = new gain_t[nframes];
1481 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1483 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1484 (*i)->set_block_size (nframes);
1487 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1488 (*i)->set_block_size (nframes);
1491 set_worst_io_latencies (false);
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 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
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() (Route* r1, 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 (Route* r1, Route* rbase)
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<Route *> existing = r1->fed_by;
1568 /* for each route that feeds r1, recurse, marking it as feeding
1572 for (set<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 (void* src)
1604 /* don't do anything here with signals emitted
1605 by Routes while we are being destroyed.
1608 if (_state_of_the_state & Deletion) {
1612 /* Caller MUST hold the route_lock */
1614 RouteList::iterator i, j;
1616 for (i = routes.begin(); i != routes.end(); ++i) {
1618 (*i)->fed_by.clear ();
1620 for (j = routes.begin(); j != routes.end(); ++j) {
1622 /* although routes can feed themselves, it will
1623 cause an endless recursive descent if we
1624 detect it. so don't bother checking for
1632 if ((*j)->feeds (*i)) {
1633 (*i)->fed_by.insert (*j);
1638 for (i = routes.begin(); i != routes.end(); ++i) {
1639 trace_terminal (*i, *i);
1646 cerr << "finished route resort\n";
1648 for (i = routes.begin(); i != routes.end(); ++i) {
1649 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1657 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1660 char track_name[32];
1662 uint32_t channels_used = 0;
1664 uint32_t nphysical_in;
1665 uint32_t nphysical_out;
1667 /* count existing audio tracks */
1670 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1671 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1672 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1673 if (!(*i)->hidden()) {
1675 channels_used += (*i)->n_inputs();
1681 /* check for duplicate route names, since we might have pre-existing
1682 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1683 save, close,restart,add new route - first named route is now
1688 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1689 if (route_by_name (track_name) == 0) {
1694 } while (n < (UINT_MAX-1));
1696 if (input_auto_connect & AutoConnectPhysical) {
1697 nphysical_in = n_physical_inputs;
1702 if (output_auto_connect & AutoConnectPhysical) {
1703 nphysical_out = n_physical_outputs;
1709 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1711 if (track->ensure_io (input_channels, output_channels, false, this)) {
1712 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1713 input_channels, output_channels)
1718 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1722 if (input_auto_connect & AutoConnectPhysical) {
1723 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1726 if (port.length() && track->connect_input (track->input (x), port, this)) {
1732 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1736 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1737 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1738 } else if (output_auto_connect & AutoConnectMaster) {
1740 port = _master_out->input (x%_master_out->n_inputs())->name();
1744 if (port.length() && track->connect_output (track->output (x), port, this)) {
1750 vector<string> cports;
1751 uint32_t ni = _control_out->n_inputs();
1753 for (n = 0; n < ni; ++n) {
1754 cports.push_back (_control_out->input(n)->name());
1757 track->set_control_outs (cports);
1760 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1764 track->set_remote_control_id (ntracks());
1767 catch (failed_constructor &err) {
1768 error << _("Session: could not create new audio track.") << endmsg;
1776 Session::new_audio_route (int input_channels, int output_channels)
1783 /* count existing audio busses */
1786 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1787 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1788 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1789 if (!(*i)->hidden()) {
1797 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1798 if (route_by_name (bus_name) == 0) {
1803 } while (n < (UINT_MAX-1));
1806 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1808 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1809 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1810 input_channels, output_channels)
1814 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1818 if (input_auto_connect & AutoConnectPhysical) {
1819 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1822 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1827 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1831 if (output_auto_connect & AutoConnectPhysical) {
1832 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1833 } else if (output_auto_connect & AutoConnectMaster) {
1835 port = _master_out->input (x%_master_out->n_inputs())->name();
1839 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1845 vector<string> cports;
1846 uint32_t ni = _control_out->n_inputs();
1848 for (uint32_t n = 0; n < ni; ++n) {
1849 cports.push_back (_control_out->input(n)->name());
1851 bus->set_control_outs (cports);
1857 catch (failed_constructor &err) {
1858 error << _("Session: could not create new route.") << endmsg;
1866 Session::add_route (Route* route)
1869 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1870 routes.push_front (route);
1874 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1875 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1876 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1877 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1879 if (route->master()) {
1880 _master_out = route;
1883 if (route->control()) {
1884 _control_out = route;
1887 AudioTrack* at = dynamic_cast<AudioTrack*>(route);
1888 if (at && at->mode() == Destructive) {
1889 destructive_index++;
1893 save_state (_current_snapshot_name);
1895 RouteAdded (route); /* EMIT SIGNAL */
1899 Session::add_diskstream (DiskStream* dstream)
1901 /* need to do this in case we're rolling at the time, to prevent false underruns */
1902 dstream->do_refill(0, 0, 0);
1905 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1906 diskstreams.push_back (dstream);
1909 /* take a reference to the diskstream, preventing it from
1910 ever being deleted until the session itself goes away,
1911 or chooses to remove it for its own purposes.
1915 dstream->set_block_size (current_block_size);
1917 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1918 /* this will connect to future changes, and check the current length */
1919 diskstream_playlist_changed (dstream);
1921 dstream->prepare ();
1924 save_state (_current_snapshot_name);
1926 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1930 Session::remove_route (Route& route)
1933 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1934 routes.remove (&route);
1936 /* deleting the master out seems like a dumb
1937 idea, but its more of a UI policy issue
1941 if (&route == _master_out) {
1945 if (&route == _control_out) {
1948 /* cancel control outs for all routes */
1950 vector<string> empty;
1952 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1953 (*r)->set_control_outs (empty);
1957 update_route_solo_state ();
1961 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1965 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1966 diskstreams.remove (&at->disk_stream());
1967 at->disk_stream().unref ();
1970 find_current_end ();
1973 update_latency_compensation (false, false);
1976 /* XXX should we disconnect from the Route's signals ? */
1978 save_state (_current_snapshot_name);
1984 Session::route_mute_changed (void* src)
1990 Session::route_solo_changed (void* src, Route* route)
1992 if (solo_update_disabled) {
1997 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2000 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2002 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2004 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2008 /* don't mess with busses */
2010 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2016 /* don't mess with tracks */
2018 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2023 if ((*i) != route &&
2024 ((*i)->mix_group () == 0 ||
2025 (*i)->mix_group () != route->mix_group () ||
2026 !route->mix_group ()->is_active())) {
2028 if ((*i)->soloed()) {
2030 /* if its already soloed, and solo latching is enabled,
2031 then leave it as it is.
2034 if (_solo_latched) {
2041 solo_update_disabled = true;
2042 (*i)->set_solo (false, src);
2043 solo_update_disabled = false;
2047 bool something_soloed = false;
2048 bool same_thing_soloed = false;
2049 bool signal = false;
2051 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2052 if ((*i)->soloed()) {
2053 something_soloed = true;
2054 if (dynamic_cast<AudioTrack*>(*i)) {
2056 same_thing_soloed = true;
2061 same_thing_soloed = true;
2069 if (something_soloed != currently_soloing) {
2071 currently_soloing = something_soloed;
2074 modify_solo_mute (is_track, same_thing_soloed);
2077 SoloActive (currently_soloing);
2084 Session::set_solo_latched (bool yn)
2086 if (yn != _solo_latched) {
2089 ControlChanged (SoloLatch);
2094 Session::update_route_solo_state ()
2097 bool is_track = false;
2098 bool signal = false;
2100 /* caller must hold RouteLock */
2102 /* this is where we actually implement solo by changing
2103 the solo mute setting of each track.
2106 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2107 if ((*i)->soloed()) {
2109 if (dynamic_cast<AudioTrack*>(*i)) {
2116 if (mute != currently_soloing) {
2118 currently_soloing = mute;
2121 if (!is_track && !mute) {
2123 /* nothing is soloed */
2125 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2126 (*i)->set_solo_mute (false);
2136 modify_solo_mute (is_track, mute);
2139 SoloActive (currently_soloing);
2144 Session::modify_solo_mute (bool is_track, bool mute)
2146 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2150 /* only alter track solo mute */
2152 if (dynamic_cast<AudioTrack*>(*i)) {
2153 if ((*i)->soloed()) {
2154 (*i)->set_solo_mute (!mute);
2156 (*i)->set_solo_mute (mute);
2162 /* only alter bus solo mute */
2164 if (!dynamic_cast<AudioTrack*>(*i)) {
2166 if ((*i)->soloed()) {
2168 (*i)->set_solo_mute (false);
2172 /* don't mute master or control outs
2173 in response to another bus solo
2176 if ((*i) != _master_out &&
2177 (*i) != _control_out) {
2178 (*i)->set_solo_mute (mute);
2189 Session::catch_up_on_solo ()
2191 /* this is called after set_state() to catch the full solo
2192 state, which can't be correctly determined on a per-route
2193 basis, but needs the global overview that only the session
2196 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2197 update_route_solo_state();
2201 Session::route_by_name (string name)
2203 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2205 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2206 if ((*i)->name() == name) {
2215 Session::route_by_remote_id (uint32_t id)
2217 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2219 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2220 if ((*i)->remote_control_id() == id) {
2229 Session::find_current_end ()
2231 jack_nframes_t max = 0;
2234 if (_state_of_the_state & Loading) {
2238 /* Don't take the diskstream lock. Caller must have other ways to
2242 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2243 Playlist* pl = (*i)->playlist();
2244 if ((me = pl->get_maximum_extent()) > max) {
2249 if (max > end_location->end()) {
2250 end_location->set_end (max);
2252 DurationChanged(); /* EMIT SIGNAL */
2257 Session::diskstream_by_name (string name)
2259 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2261 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2262 if ((*i)->name() == name) {
2271 Session::diskstream_by_id (id_t id)
2273 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2275 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2276 if ((*i)->id() == id) {
2284 /* AudioRegion management */
2287 Session::new_region_name (string old)
2289 string::size_type last_period;
2291 string::size_type len = old.length() + 64;
2294 if ((last_period = old.find_last_of ('.')) == string::npos) {
2296 /* no period present - add one explicitly */
2299 last_period = old.length() - 1;
2304 number = atoi (old.substr (last_period+1).c_str());
2308 while (number < (UINT_MAX-1)) {
2310 AudioRegionList::const_iterator i;
2315 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2318 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2319 if ((*i).second->name() == sbuf) {
2324 if (i == audio_regions.end()) {
2329 if (number != (UINT_MAX-1)) {
2333 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2338 Session::region_name (string& result, string base, bool newlevel) const
2345 LockMonitor lm (region_lock, __LINE__, __FILE__);
2347 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2355 /* XXX this is going to be slow. optimize me later */
2360 string::size_type pos;
2362 pos = base.find_last_of ('.');
2364 /* pos may be npos, but then we just use entire base */
2366 subbase = base.substr (0, pos);
2370 bool name_taken = true;
2373 LockMonitor lm (region_lock, __LINE__, __FILE__);
2375 for (int n = 1; n < 5000; ++n) {
2378 snprintf (buf, sizeof (buf), ".%d", n);
2383 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2384 if ((*i).second->name() == result) {
2397 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2405 Session::add_region (Region* region)
2407 AudioRegion* ar = 0;
2408 AudioRegion* oar = 0;
2412 LockMonitor lm (region_lock, __LINE__, __FILE__);
2414 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2416 AudioRegionList::iterator x;
2418 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2420 oar = dynamic_cast<AudioRegion*> (x->second);
2422 if (ar->region_list_equivalent (*oar)) {
2427 if (x == audio_regions.end()) {
2429 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2431 entry.first = region->id();
2434 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2445 fatal << _("programming error: ")
2446 << X_("unknown region type passed to Session::add_region()")
2453 /* mark dirty because something has changed even if we didn't
2454 add the region to the region list.
2460 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2461 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2462 AudioRegionAdded (ar); /* EMIT SIGNAL */
2467 Session::region_changed (Change what_changed, Region* region)
2469 if (what_changed & Region::HiddenChanged) {
2470 /* relay hidden changes */
2471 RegionHiddenChange (region);
2476 Session::region_renamed (Region* region)
2478 add_region (region);
2482 Session::remove_region (Region* region)
2484 AudioRegionList::iterator i;
2485 AudioRegion* ar = 0;
2486 bool removed = false;
2489 LockMonitor lm (region_lock, __LINE__, __FILE__);
2491 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2492 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2493 audio_regions.erase (i);
2497 fatal << _("programming error: ")
2498 << X_("unknown region type passed to Session::remove_region()")
2504 /* mark dirty because something has changed even if we didn't
2505 remove the region from the region list.
2511 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2516 Session::find_whole_file_parent (AudioRegion& child)
2518 AudioRegionList::iterator i;
2519 AudioRegion* region;
2520 LockMonitor lm (region_lock, __LINE__, __FILE__);
2522 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2524 region = (*i).second;
2526 if (region->whole_file()) {
2528 if (child.source_equivalent (*region)) {
2538 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2540 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2544 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2548 pl->get_region_list_equivalent_regions (region, result);
2553 Session::destroy_region (Region* region)
2555 AudioRegion* aregion;
2557 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2561 if (aregion->playlist()) {
2562 aregion->playlist()->destroy_region (region);
2565 vector<Source*> srcs;
2567 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2568 srcs.push_back (&aregion->source (n));
2571 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2573 if ((*i)->use_cnt() == 0) {
2574 (*i)->mark_for_remove ();
2583 Session::destroy_regions (list<Region*> regions)
2585 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2586 destroy_region (*i);
2592 Session::remove_last_capture ()
2596 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2598 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2599 list<Region*>& l = (*i)->last_capture_regions();
2602 r.insert (r.end(), l.begin(), l.end());
2607 destroy_regions (r);
2612 Session::remove_region_from_region_list (Region& r)
2618 /* Source Management */
2621 Session::add_source (Source* source)
2623 pair<SourceList::key_type, SourceList::mapped_type> entry;
2626 LockMonitor lm (source_lock, __LINE__, __FILE__);
2627 entry.first = source->id();
2628 entry.second = source;
2629 sources.insert (entry);
2632 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2635 SourceAdded (source); /* EMIT SIGNAL */
2639 Session::remove_source (Source* source)
2641 SourceList::iterator i;
2644 LockMonitor lm (source_lock, __LINE__, __FILE__);
2646 if ((i = sources.find (source->id())) != sources.end()) {
2651 if (!_state_of_the_state & InCleanup) {
2653 /* save state so we don't end up with a session file
2654 referring to non-existent sources.
2657 save_state (_current_snapshot_name);
2660 SourceRemoved(source); /* EMIT SIGNAL */
2664 Session::get_source (ARDOUR::id_t id)
2666 LockMonitor lm (source_lock, __LINE__, __FILE__);
2667 SourceList::iterator i;
2670 if ((i = sources.find (id)) != sources.end()) {
2671 source = (*i).second;
2678 Session::peak_path_from_audio_path (string audio_path)
2680 /* XXX hardly bombproof! fix me */
2684 res = PBD::dirname (audio_path);
2685 res = PBD::dirname (res);
2687 res += peak_dir_name;
2689 res += PBD::basename_nosuffix (audio_path);
2696 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2699 string old_basename = basename_nosuffix (oldname);
2700 string new_legalized = legalize_for_path (newname);
2702 /* note: we know (or assume) the old path is already valid */
2706 /* destructive file sources have a name of the form:
2708 /path/to/Tnnnn-NAME(%[LR])?.wav
2710 the task here is to replace NAME with the new name.
2713 /* find last slash */
2717 string::size_type slash;
2718 string::size_type dash;
2720 if ((slash = path.find_last_of ('/')) == string::npos) {
2724 dir = path.substr (0, slash+1);
2726 /* '-' is not a legal character for the NAME part of the path */
2728 if ((dash = path.find_last_of ('-')) == string::npos) {
2732 prefix = path.substr (slash+1, dash-(slash+1));
2737 path += new_legalized;
2738 path += ".wav"; /* XXX gag me with a spoon */
2742 /* non-destructive file sources have a name of the form:
2744 /path/to/NAME-nnnnn(%[LR])?.wav
2746 the task here is to replace NAME with the new name.
2749 /* find last slash */
2753 string::size_type slash;
2754 string::size_type dash;
2756 if ((slash = path.find_last_of ('/')) == string::npos) {
2760 dir = path.substr (0, slash+1);
2762 /* '-' is not a legal character for the NAME part of the path */
2764 if ((dash = path.find_last_of ('-')) == string::npos) {
2768 suffix = path.substr (dash);
2771 path += new_legalized;
2779 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2783 char buf[PATH_MAX+1];
2784 const uint32_t limit = 10000;
2788 legalized = legalize_for_path (name);
2790 /* find a "version" of the file name that doesn't exist in
2791 any of the possible directories.
2794 for (cnt = (destructive ? destructive_index + 1 : 1); cnt <= limit; ++cnt) {
2796 vector<space_and_path>::iterator i;
2797 uint32_t existing = 0;
2799 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2804 spath += tape_dir_name;
2806 spath += sound_dir_name;
2811 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2812 } else if (nchan == 2) {
2814 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2816 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2818 } else if (nchan < 26) {
2819 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2821 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2829 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2830 } else if (nchan == 2) {
2832 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2834 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2836 } else if (nchan < 26) {
2837 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2839 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2843 if (access (buf, F_OK) == 0) {
2848 if (existing == 0) {
2853 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2854 throw failed_constructor();
2858 /* we now have a unique name for the file, but figure out where to
2865 spath = tape_dir ();
2867 spath = discover_best_sound_dir ();
2870 string::size_type pos = foo.find_last_of ('/');
2872 if (pos == string::npos) {
2875 spath += foo.substr (pos + 1);
2882 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2884 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2886 /* this might throw failed_constructor(), which is OK */
2889 return new DestructiveFileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2891 return new FileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2895 /* Playlist management */
2898 Session::get_playlist (string name)
2902 if ((ret = playlist_by_name (name)) == 0) {
2903 ret = new AudioPlaylist (*this, name);
2910 Session::playlist_by_name (string name)
2912 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2913 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2914 if ((*i)->name() == name) {
2918 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2919 if ((*i)->name() == name) {
2927 Session::add_playlist (Playlist* playlist)
2929 if (playlist->hidden()) {
2934 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2935 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2936 playlists.insert (playlists.begin(), playlist);
2938 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2939 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2945 PlaylistAdded (playlist); /* EMIT SIGNAL */
2949 Session::track_playlist (Playlist* pl, bool inuse)
2951 PlaylistList::iterator x;
2954 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2957 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2959 unused_playlists.insert (pl);
2961 if ((x = playlists.find (pl)) != playlists.end()) {
2962 playlists.erase (x);
2967 //cerr << "shifting playlist to used: " << pl->name() << endl;
2969 playlists.insert (pl);
2971 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2972 unused_playlists.erase (x);
2979 Session::remove_playlist (Playlist* playlist)
2981 if (_state_of_the_state & Deletion) {
2986 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2987 // cerr << "removing playlist: " << playlist->name() << endl;
2989 PlaylistList::iterator i;
2991 i = find (playlists.begin(), playlists.end(), playlist);
2993 if (i != playlists.end()) {
2994 playlists.erase (i);
2997 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2998 if (i != unused_playlists.end()) {
2999 unused_playlists.erase (i);
3006 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3010 Session::set_audition (AudioRegion* r)
3012 pending_audition_region = r;
3013 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3014 schedule_butler_transport_work ();
3018 Session::non_realtime_set_audition ()
3020 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3021 auditioner->audition_current_playlist ();
3022 } else if (pending_audition_region) {
3023 auditioner->audition_region (*pending_audition_region);
3025 pending_audition_region = 0;
3026 AuditionActive (true); /* EMIT SIGNAL */
3030 Session::audition_playlist ()
3032 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3033 ev->set_ptr ((void*) 0xfeedface);
3038 Session::audition_region (AudioRegion& r)
3040 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3046 Session::cancel_audition ()
3048 if (auditioner->active()) {
3049 auditioner->cancel_audition ();
3050 AuditionActive (false); /* EMIT SIGNAL */
3055 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3057 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3061 Session::remove_empty_sounds ()
3064 PathScanner scanner;
3069 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3071 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3073 if (FileSource::is_empty (*(*i))) {
3075 unlink ((*i)->c_str());
3077 string peak_path = peak_path_from_audio_path (**i);
3078 unlink (peak_path.c_str());
3084 delete possible_audiofiles;
3088 Session::is_auditioning () const
3090 /* can be called before we have an auditioner object */
3092 return auditioner->active();
3099 Session::set_all_solo (bool yn)
3102 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3104 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3105 if (!(*i)->hidden()) {
3106 (*i)->set_solo (yn, this);
3115 Session::set_all_mute (bool yn)
3118 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3120 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3121 if (!(*i)->hidden()) {
3122 (*i)->set_mute (yn, this);
3131 Session::n_diskstreams () const
3133 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3136 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3137 if (!(*i)->hidden()) {
3145 Session::foreach_diskstream (void (DiskStream::*func)(void))
3147 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3148 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3149 if (!(*i)->hidden()) {
3156 Session::graph_reordered ()
3158 /* don't do this stuff if we are setting up connections
3159 from a set_state() call.
3162 if (_state_of_the_state & InitialConnecting) {
3166 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3167 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3171 /* force all diskstreams to update their capture offset values to
3172 reflect any changes in latencies within the graph.
3175 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3176 (*i)->set_capture_offset ();
3181 Session::record_disenable_all ()
3183 record_enable_change_all (false);
3187 Session::record_enable_all ()
3189 record_enable_change_all (true);
3193 Session::record_enable_change_all (bool yn)
3195 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3197 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3200 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3201 at->set_record_enable (yn, this);
3205 /* since we don't keep rec-enable state, don't mark session dirty */
3209 Session::add_redirect (Redirect* redirect)
3213 PortInsert* port_insert;
3214 PluginInsert* plugin_insert;
3216 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3217 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3218 _port_inserts.insert (_port_inserts.begin(), port_insert);
3219 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3220 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3222 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3225 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3226 _sends.insert (_sends.begin(), send);
3228 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3232 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3238 Session::remove_redirect (Redirect* redirect)
3242 PortInsert* port_insert;
3243 PluginInsert* plugin_insert;
3245 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3246 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3247 _port_inserts.remove (port_insert);
3248 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3249 _plugin_inserts.remove (plugin_insert);
3251 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3254 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3255 _sends.remove (send);
3257 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3265 Session::available_capture_duration ()
3267 const double scale = 4096.0 / sizeof (Sample);
3269 if (_total_free_4k_blocks * scale > (double) max_frames) {
3273 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3277 Session::add_connection (ARDOUR::Connection* connection)
3280 LockMonitor (connection_lock, __LINE__, __FILE__);
3281 _connections.push_back (connection);
3284 ConnectionAdded (connection); /* EMIT SIGNAL */
3290 Session::remove_connection (ARDOUR::Connection* connection)
3292 bool removed = false;
3295 LockMonitor (connection_lock, __LINE__, __FILE__);
3296 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3298 if (i != _connections.end()) {
3299 _connections.erase (i);
3305 ConnectionRemoved (connection); /* EMIT SIGNAL */
3311 ARDOUR::Connection *
3312 Session::connection_by_name (string name) const
3314 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3316 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3317 if ((*i)->name() == name) {
3326 Session::set_edit_mode (EditMode mode)
3331 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3333 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3334 (*i)->set_edit_mode (mode);
3339 ControlChanged (EditingMode); /* EMIT SIGNAL */
3343 Session::tempo_map_changed (Change ignored)
3350 Session::ensure_passthru_buffers (uint32_t howmany)
3352 while (howmany > _passthru_buffers.size()) {
3354 #ifdef NO_POSIX_MEMALIGN
3355 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3357 posix_memalign((void **)&p,16,current_block_size * 4);
3359 _passthru_buffers.push_back (p);
3363 #ifdef NO_POSIX_MEMALIGN
3364 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3366 posix_memalign((void **)&p,16,current_block_size * 4);
3368 memset (p, 0, sizeof (Sample) * current_block_size);
3369 _silent_buffers.push_back (p);
3373 #ifdef NO_POSIX_MEMALIGN
3374 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3376 posix_memalign((void **)&p,16,current_block_size * 4);
3378 memset (p, 0, sizeof (Sample) * current_block_size);
3379 _send_buffers.push_back (p);
3382 allocate_pan_automation_buffers (current_block_size, howmany, false);
3386 Session::next_send_name ()
3389 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3394 Session::next_insert_name ()
3397 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3401 /* Named Selection management */
3404 Session::named_selection_by_name (string name)
3406 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3407 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3408 if ((*i)->name == name) {
3416 Session::add_named_selection (NamedSelection* named_selection)
3419 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3420 named_selections.insert (named_selections.begin(), named_selection);
3425 NamedSelectionAdded (); /* EMIT SIGNAL */
3429 Session::remove_named_selection (NamedSelection* named_selection)
3431 bool removed = false;
3434 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3436 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3438 if (i != named_selections.end()) {
3440 named_selections.erase (i);
3447 NamedSelectionRemoved (); /* EMIT SIGNAL */
3452 Session::reset_native_file_format ()
3454 // jlc - WHY take routelock?
3455 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3456 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3458 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3459 (*i)->reset_write_sources (false);
3464 Session::route_name_unique (string n) const
3466 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3468 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3469 if ((*i)->name() == n) {
3478 Session::remove_file_source (FileSource& fs)
3480 return fs.move_to_trash (dead_sound_dir_name);
3484 Session::n_playlists () const
3486 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3487 return playlists.size();
3491 Session::set_solo_model (SoloModel sm)
3493 if (sm != _solo_model) {
3495 ControlChanged (SoloingModel);
3501 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3503 if (!force && howmany <= _npan_buffers) {
3507 if (_pan_automation_buffer) {
3509 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3510 delete [] _pan_automation_buffer[i];
3513 delete [] _pan_automation_buffer;
3516 _pan_automation_buffer = new pan_t*[howmany];
3518 for (uint32_t i = 0; i < howmany; ++i) {
3519 _pan_automation_buffer[i] = new pan_t[nframes];
3522 _npan_buffers = howmany;
3526 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3528 Stateful::add_instant_xml (node, dir);
3529 Config->add_instant_xml (node, get_user_ardour_path());
3533 Session::freeze (InterThreadInfo& itt)
3535 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3537 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3541 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3542 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3553 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3554 InterThreadInfo& itt)
3558 FileSource* fsource;
3560 char buf[PATH_MAX+1];
3563 jack_nframes_t position;
3564 jack_nframes_t this_chunk;
3565 jack_nframes_t to_do;
3566 vector<Sample*> buffers;
3568 const jack_nframes_t chunk_size = (256 * 1024)/4;
3570 atomic_set (&processing_prohibited, 1);
3572 /* call tree *MUST* hold route_lock */
3574 if ((playlist = track.disk_stream().playlist()) == 0) {
3578 /* external redirects will be a problem */
3580 if (track.has_external_redirects()) {
3584 nchans = track.disk_stream().n_channels();
3586 dir = discover_best_sound_dir ();
3588 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3590 for (x = 0; x < 99999; ++x) {
3591 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3592 if (access (buf, F_OK) != 0) {
3598 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3603 fsource = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format());
3606 catch (failed_constructor& err) {
3607 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3611 srcs.push_back(fsource);
3614 /* XXX need to flush all redirects */
3619 /* create a set of reasonably-sized buffers */
3621 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3623 #ifdef NO_POSIX_MEMALIGN
3624 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3626 posix_memalign((void **)&b,16,chunk_size * 4);
3628 buffers.push_back (b);
3631 workbuf = new char[chunk_size * 4];
3633 while (to_do && !itt.cancel) {
3635 this_chunk = min (to_do, chunk_size);
3637 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3642 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3643 if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3648 start += this_chunk;
3649 to_do -= this_chunk;
3651 itt.progress = (float) (1.0 - ((double) to_do / len));
3660 xnow = localtime (&now);
3662 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3663 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3666 /* build peakfile for new source */
3668 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3669 dynamic_cast<FileSource*>(*src)->build_peaks ();
3677 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3678 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3683 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3691 atomic_set (&processing_prohibited, 0);
3699 Session::get_silent_buffers (uint32_t howmany)
3701 for (uint32_t i = 0; i < howmany; ++i) {
3702 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3704 return _silent_buffers;
3708 Session::ntracks () const
3711 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3713 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3714 if (dynamic_cast<AudioTrack*> (*i)) {
3723 Session::nbusses () const
3726 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3728 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3729 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3738 Session::set_layer_model (LayerModel lm)
3740 if (lm != layer_model) {
3743 ControlChanged (LayeringModel);
3748 Session::set_xfade_model (CrossfadeModel xm)
3750 if (xm != xfade_model) {
3753 ControlChanged (CrossfadingModel);