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 (slist<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 (slist<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 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 */
1302 remove_pending_capture_state ();
1307 Session::step_back_from_record ()
1309 atomic_set (&_record_status, Enabled);
1311 if (Config->get_use_hardware_monitoring()) {
1312 /* Even though this can be called from RT context we are using
1313 a non-tentative rwlock here, because the action must occur.
1314 The rarity and short potential lock duration makes this "OK"
1316 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1318 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1319 if (auto_input && (*i)->record_enabled ()) {
1320 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1321 (*i)->monitor_input (false);
1328 Session::maybe_enable_record ()
1330 atomic_set (&_record_status, Enabled);
1332 /* XXX this save should really happen in another thread. its needed so that
1333 pending capture state can be recovered if we crash.
1336 save_state ("", true);
1338 if (_transport_speed) {
1343 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1344 RecordStateChanged (); /* EMIT SIGNAL */
1351 Session::audible_frame () const
1354 jack_nframes_t offset;
1357 /* the first of these two possible settings for "offset"
1358 mean that the audible frame is stationary until
1359 audio emerges from the latency compensation
1362 the second means that the audible frame is stationary
1363 until audio would emerge from a physical port
1364 in the absence of any plugin latency compensation
1367 offset = _worst_output_latency;
1369 if (offset > current_block_size) {
1370 offset -= current_block_size;
1372 /* XXX is this correct? if we have no external
1373 physical connections and everything is internal
1374 then surely this is zero? still, how
1375 likely is that anyway?
1377 offset = current_block_size;
1380 if (synced_to_jack()) {
1381 tf = _engine.transport_frame();
1383 tf = _transport_frame;
1386 if (_transport_speed == 0) {
1396 if (!non_realtime_work_pending()) {
1400 /* take latency into account */
1409 Session::set_frame_rate (jack_nframes_t frames_per_second)
1411 /** \fn void Session::set_frame_size(jack_nframes_t)
1412 the AudioEngine object that calls this guarantees
1413 that it will not be called while we are also in
1414 ::process(). Its fine to do things that block
1418 _current_frame_rate = frames_per_second;
1419 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1421 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1425 /* XXX need to reset/reinstantiate all LADSPA plugins */
1429 Session::set_block_size (jack_nframes_t nframes)
1431 /* the AudioEngine guarantees
1432 that it will not be called while we are also in
1433 ::process(). It is therefore fine to do things that block
1438 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1439 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1440 vector<Sample*>::iterator i;
1443 current_block_size = nframes;
1445 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1449 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1453 _passthru_buffers.clear ();
1454 _silent_buffers.clear ();
1456 ensure_passthru_buffers (np);
1458 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1462 #ifdef NO_POSIX_MEMALIGN
1463 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1465 posix_memalign((void **)&buf,16,current_block_size * 4);
1469 memset (*i, 0, sizeof (Sample) * current_block_size);
1473 if (_gain_automation_buffer) {
1474 delete [] _gain_automation_buffer;
1476 _gain_automation_buffer = new gain_t[nframes];
1478 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1480 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1481 (*i)->set_block_size (nframes);
1484 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1485 (*i)->set_block_size (nframes);
1488 set_worst_io_latencies (false);
1493 Session::set_default_fade (float steepness, float fade_msecs)
1496 jack_nframes_t fade_frames;
1498 /* Don't allow fade of less 1 frame */
1500 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1507 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1511 default_fade_msecs = fade_msecs;
1512 default_fade_steepness = steepness;
1515 // jlc, WTF is this!
1516 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1517 AudioRegion::set_default_fade (steepness, fade_frames);
1522 /* XXX have to do this at some point */
1523 /* foreach region using default fade, reset, then
1524 refill_all_diskstream_buffers ();
1529 struct RouteSorter {
1530 bool operator() (Route* r1, Route* r2) {
1531 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1533 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1536 if (r1->fed_by.empty()) {
1537 if (r2->fed_by.empty()) {
1538 /* no ardour-based connections inbound to either route. just use signal order */
1539 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1541 /* r2 has connections, r1 does not; run r1 early */
1545 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1552 trace_terminal (Route* r1, Route* rbase)
1556 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1557 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1561 /* make a copy of the existing list of routes that feed r1 */
1563 set<Route *> existing = r1->fed_by;
1565 /* for each route that feeds r1, recurse, marking it as feeding
1569 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1572 /* r2 is a route that feeds r1 which somehow feeds base. mark
1573 base as being fed by r2
1576 rbase->fed_by.insert (r2);
1580 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1584 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1588 /* now recurse, so that we can mark base as being fed by
1589 all routes that feed r2
1592 trace_terminal (r2, rbase);
1599 Session::resort_routes (void* src)
1601 /* don't do anything here with signals emitted
1602 by Routes while we are being destroyed.
1605 if (_state_of_the_state & Deletion) {
1609 /* Caller MUST hold the route_lock */
1611 RouteList::iterator i, j;
1613 for (i = routes.begin(); i != routes.end(); ++i) {
1615 (*i)->fed_by.clear ();
1617 for (j = routes.begin(); j != routes.end(); ++j) {
1619 /* although routes can feed themselves, it will
1620 cause an endless recursive descent if we
1621 detect it. so don't bother checking for
1629 if ((*j)->feeds (*i)) {
1630 (*i)->fed_by.insert (*j);
1635 for (i = routes.begin(); i != routes.end(); ++i) {
1636 trace_terminal (*i, *i);
1643 cerr << "finished route resort\n";
1645 for (i = routes.begin(); i != routes.end(); ++i) {
1646 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1654 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1657 char track_name[32];
1659 uint32_t channels_used = 0;
1661 uint32_t nphysical_in;
1662 uint32_t nphysical_out;
1664 /* count existing audio tracks */
1667 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1668 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1669 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1670 if (!(*i)->hidden()) {
1672 channels_used += (*i)->n_inputs();
1678 /* check for duplicate route names, since we might have pre-existing
1679 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1680 save, close,restart,add new route - first named route is now
1685 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1686 if (route_by_name (track_name) == 0) {
1691 } while (n < (UINT_MAX-1));
1693 if (input_auto_connect & AutoConnectPhysical) {
1694 nphysical_in = n_physical_inputs;
1699 if (output_auto_connect & AutoConnectPhysical) {
1700 nphysical_out = n_physical_outputs;
1706 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1708 if (track->ensure_io (input_channels, output_channels, false, this)) {
1709 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1710 input_channels, output_channels)
1715 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1719 if (input_auto_connect & AutoConnectPhysical) {
1720 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1723 if (port.length() && track->connect_input (track->input (x), port, this)) {
1729 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1733 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1734 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1735 } else if (output_auto_connect & AutoConnectMaster) {
1737 port = _master_out->input (x%_master_out->n_inputs())->name();
1741 if (port.length() && track->connect_output (track->output (x), port, this)) {
1747 vector<string> cports;
1748 uint32_t ni = _control_out->n_inputs();
1750 for (n = 0; n < ni; ++n) {
1751 cports.push_back (_control_out->input(n)->name());
1754 track->set_control_outs (cports);
1757 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1761 track->set_remote_control_id (ntracks());
1764 catch (failed_constructor &err) {
1765 error << _("Session: could not create new audio track.") << endmsg;
1773 Session::new_audio_route (int input_channels, int output_channels)
1780 /* count existing audio busses */
1783 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1784 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1785 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1786 if (!(*i)->hidden()) {
1794 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1795 if (route_by_name (bus_name) == 0) {
1800 } while (n < (UINT_MAX-1));
1803 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1805 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1811 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1815 if (input_auto_connect & AutoConnectPhysical) {
1816 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1819 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1824 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1828 if (output_auto_connect & AutoConnectPhysical) {
1829 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1830 } else if (output_auto_connect & AutoConnectMaster) {
1832 port = _master_out->input (x%_master_out->n_inputs())->name();
1836 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1842 vector<string> cports;
1843 uint32_t ni = _control_out->n_inputs();
1845 for (uint32_t n = 0; n < ni; ++n) {
1846 cports.push_back (_control_out->input(n)->name());
1848 bus->set_control_outs (cports);
1854 catch (failed_constructor &err) {
1855 error << _("Session: could not create new route.") << endmsg;
1863 Session::add_route (Route* route)
1866 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1867 routes.push_front (route);
1871 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1872 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1873 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1874 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1876 if (route->master()) {
1877 _master_out = route;
1880 if (route->control()) {
1881 _control_out = route;
1884 AudioTrack* at = dynamic_cast<AudioTrack*>(route);
1885 if (at && at->mode() == Destructive) {
1886 destructive_index++;
1890 save_state (_current_snapshot_name);
1892 RouteAdded (route); /* EMIT SIGNAL */
1896 Session::add_diskstream (DiskStream* dstream)
1898 /* need to do this in case we're rolling at the time, to prevent false underruns */
1899 dstream->do_refill(0, 0, 0);
1902 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1903 diskstreams.push_back (dstream);
1906 /* take a reference to the diskstream, preventing it from
1907 ever being deleted until the session itself goes away,
1908 or chooses to remove it for its own purposes.
1912 dstream->set_block_size (current_block_size);
1914 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1915 /* this will connect to future changes, and check the current length */
1916 diskstream_playlist_changed (dstream);
1918 dstream->prepare ();
1921 save_state (_current_snapshot_name);
1923 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1927 Session::remove_route (Route& route)
1930 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1931 routes.remove (&route);
1933 /* deleting the master out seems like a dumb
1934 idea, but its more of a UI policy issue
1938 if (&route == _master_out) {
1942 if (&route == _control_out) {
1945 /* cancel control outs for all routes */
1947 vector<string> empty;
1949 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1950 (*r)->set_control_outs (empty);
1954 update_route_solo_state ();
1958 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1962 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1963 diskstreams.remove (&at->disk_stream());
1964 at->disk_stream().unref ();
1967 find_current_end ();
1970 update_latency_compensation (false, false);
1973 /* XXX should we disconnect from the Route's signals ? */
1975 save_state (_current_snapshot_name);
1981 Session::route_mute_changed (void* src)
1987 Session::route_solo_changed (void* src, Route* route)
1989 if (solo_update_disabled) {
1994 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1997 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1999 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2001 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2005 /* don't mess with busses */
2007 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2013 /* don't mess with tracks */
2015 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2020 if ((*i) != route &&
2021 ((*i)->mix_group () == 0 ||
2022 (*i)->mix_group () != route->mix_group () ||
2023 !route->mix_group ()->is_active())) {
2025 if ((*i)->soloed()) {
2027 /* if its already soloed, and solo latching is enabled,
2028 then leave it as it is.
2031 if (_solo_latched) {
2038 solo_update_disabled = true;
2039 (*i)->set_solo (false, src);
2040 solo_update_disabled = false;
2044 bool something_soloed = false;
2045 bool same_thing_soloed = false;
2046 bool signal = false;
2048 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2049 if ((*i)->soloed()) {
2050 something_soloed = true;
2051 if (dynamic_cast<AudioTrack*>(*i)) {
2053 same_thing_soloed = true;
2058 same_thing_soloed = true;
2066 if (something_soloed != currently_soloing) {
2068 currently_soloing = something_soloed;
2071 modify_solo_mute (is_track, same_thing_soloed);
2074 SoloActive (currently_soloing);
2081 Session::set_solo_latched (bool yn)
2083 if (yn != _solo_latched) {
2086 ControlChanged (SoloLatch);
2091 Session::update_route_solo_state ()
2094 bool is_track = false;
2095 bool signal = false;
2097 /* caller must hold RouteLock */
2099 /* this is where we actually implement solo by changing
2100 the solo mute setting of each track.
2103 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2104 if ((*i)->soloed()) {
2106 if (dynamic_cast<AudioTrack*>(*i)) {
2113 if (mute != currently_soloing) {
2115 currently_soloing = mute;
2118 if (!is_track && !mute) {
2120 /* nothing is soloed */
2122 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2123 (*i)->set_solo_mute (false);
2133 modify_solo_mute (is_track, mute);
2136 SoloActive (currently_soloing);
2141 Session::modify_solo_mute (bool is_track, bool mute)
2143 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2147 /* only alter track solo mute */
2149 if (dynamic_cast<AudioTrack*>(*i)) {
2150 if ((*i)->soloed()) {
2151 (*i)->set_solo_mute (!mute);
2153 (*i)->set_solo_mute (mute);
2159 /* only alter bus solo mute */
2161 if (!dynamic_cast<AudioTrack*>(*i)) {
2163 if ((*i)->soloed()) {
2165 (*i)->set_solo_mute (false);
2169 /* don't mute master or control outs
2170 in response to another bus solo
2173 if ((*i) != _master_out &&
2174 (*i) != _control_out) {
2175 (*i)->set_solo_mute (mute);
2186 Session::catch_up_on_solo ()
2188 /* this is called after set_state() to catch the full solo
2189 state, which can't be correctly determined on a per-route
2190 basis, but needs the global overview that only the session
2193 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2194 update_route_solo_state();
2198 Session::route_by_name (string name)
2200 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2202 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2203 if ((*i)->name() == name) {
2212 Session::find_current_end ()
2214 jack_nframes_t max = 0;
2217 if (_state_of_the_state & Loading) {
2221 /* Don't take the diskstream lock. Caller must have other ways to
2225 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2226 Playlist* pl = (*i)->playlist();
2227 if ((me = pl->get_maximum_extent()) > max) {
2232 if (max > end_location->end()) {
2233 end_location->set_end (max);
2235 DurationChanged(); /* EMIT SIGNAL */
2240 Session::diskstream_by_name (string name)
2242 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2244 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2245 if ((*i)->name() == name) {
2254 Session::diskstream_by_id (id_t id)
2256 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2258 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2259 if ((*i)->id() == id) {
2267 /* AudioRegion management */
2270 Session::new_region_name (string old)
2272 string::size_type last_period;
2274 string::size_type len = old.length() + 64;
2277 if ((last_period = old.find_last_of ('.')) == string::npos) {
2279 /* no period present - add one explicitly */
2282 last_period = old.length() - 1;
2287 number = atoi (old.substr (last_period+1).c_str());
2291 while (number < (UINT_MAX-1)) {
2293 AudioRegionList::const_iterator i;
2298 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2301 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2302 if ((*i).second->name() == sbuf) {
2307 if (i == audio_regions.end()) {
2312 if (number != (UINT_MAX-1)) {
2316 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2321 Session::region_name (string& result, string base, bool newlevel) const
2328 LockMonitor lm (region_lock, __LINE__, __FILE__);
2330 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2338 /* XXX this is going to be slow. optimize me later */
2343 string::size_type pos;
2345 if ((pos = base.find_last_of ('-')) == string::npos) {
2346 pos = base.find_last_of ('.');
2349 /* pos may be npos, but then we just use entire base */
2351 subbase = base.substr (0, pos);
2354 bool name_taken = true;
2357 LockMonitor lm (region_lock, __LINE__, __FILE__);
2359 for (int n = 1; n < 5000; ++n) {
2362 snprintf (buf, sizeof (buf), ".%d", n);
2367 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2368 if ((*i).second->name() == result) {
2381 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2390 Session::add_region (Region* region)
2392 AudioRegion* ar = 0;
2393 AudioRegion* oar = 0;
2397 LockMonitor lm (region_lock, __LINE__, __FILE__);
2399 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2401 AudioRegionList::iterator x;
2403 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2405 oar = dynamic_cast<AudioRegion*> (x->second);
2407 if (ar->region_list_equivalent (*oar)) {
2412 if (x == audio_regions.end()) {
2414 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2416 entry.first = region->id();
2419 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2430 fatal << _("programming error: ")
2431 << X_("unknown region type passed to Session::add_region()")
2438 /* mark dirty because something has changed even if we didn't
2439 add the region to the region list.
2445 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2446 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2447 AudioRegionAdded (ar); /* EMIT SIGNAL */
2452 Session::region_changed (Change what_changed, Region* region)
2454 if (what_changed & Region::HiddenChanged) {
2455 /* relay hidden changes */
2456 RegionHiddenChange (region);
2461 Session::region_renamed (Region* region)
2463 add_region (region);
2467 Session::remove_region (Region* region)
2469 AudioRegionList::iterator i;
2470 AudioRegion* ar = 0;
2471 bool removed = false;
2474 LockMonitor lm (region_lock, __LINE__, __FILE__);
2476 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2477 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2478 audio_regions.erase (i);
2482 fatal << _("programming error: ")
2483 << X_("unknown region type passed to Session::remove_region()")
2489 /* mark dirty because something has changed even if we didn't
2490 remove the region from the region list.
2496 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2501 Session::find_whole_file_parent (AudioRegion& child)
2503 AudioRegionList::iterator i;
2504 AudioRegion* region;
2505 LockMonitor lm (region_lock, __LINE__, __FILE__);
2507 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2509 region = (*i).second;
2511 if (region->whole_file()) {
2513 if (child.source_equivalent (*region)) {
2523 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2525 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2529 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2533 pl->get_region_list_equivalent_regions (region, result);
2538 Session::destroy_region (Region* region)
2540 AudioRegion* aregion;
2542 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2546 if (aregion->playlist()) {
2547 aregion->playlist()->destroy_region (region);
2550 vector<Source*> srcs;
2552 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2553 srcs.push_back (&aregion->source (n));
2556 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2558 if ((*i)->use_cnt() == 0) {
2559 (*i)->mark_for_remove ();
2568 Session::destroy_regions (list<Region*> regions)
2570 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2571 destroy_region (*i);
2577 Session::remove_last_capture ()
2581 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2583 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2584 list<Region*>& l = (*i)->last_capture_regions();
2587 r.insert (r.end(), l.begin(), l.end());
2592 destroy_regions (r);
2597 Session::remove_region_from_region_list (Region& r)
2603 /* Source Management */
2606 Session::add_source (Source* source)
2608 pair<SourceList::key_type, SourceList::mapped_type> entry;
2611 LockMonitor lm (source_lock, __LINE__, __FILE__);
2612 entry.first = source->id();
2613 entry.second = source;
2614 sources.insert (entry);
2617 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2620 SourceAdded (source); /* EMIT SIGNAL */
2624 Session::remove_source (Source* source)
2626 SourceList::iterator i;
2629 LockMonitor lm (source_lock, __LINE__, __FILE__);
2631 if ((i = sources.find (source->id())) != sources.end()) {
2636 if (!_state_of_the_state & InCleanup) {
2638 /* save state so we don't end up with a session file
2639 referring to non-existent sources.
2642 save_state (_current_snapshot_name);
2645 SourceRemoved(source); /* EMIT SIGNAL */
2649 Session::get_source (ARDOUR::id_t id)
2651 LockMonitor lm (source_lock, __LINE__, __FILE__);
2652 SourceList::iterator i;
2655 if ((i = sources.find (id)) != sources.end()) {
2656 source = (*i).second;
2663 Session::peak_path_from_audio_path (string audio_path)
2665 /* XXX hardly bombproof! fix me */
2669 res = PBD::dirname (audio_path);
2670 res = PBD::dirname (res);
2672 res += peak_dir_name;
2674 res += PBD::basename_nosuffix (audio_path);
2681 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2684 string old_basename = basename_nosuffix (oldname);
2685 string new_legalized = legalize_for_path (newname);
2687 /* note: we know (or assume) the old path is already valid */
2691 /* destructive file sources have a name of the form:
2693 /path/to/Tnnnn-NAME(%[LR])?.wav
2695 the task here is to replace NAME with the new name.
2698 /* find last slash */
2702 string::size_type slash;
2703 string::size_type dash;
2705 if ((slash = path.find_last_of ('/')) == string::npos) {
2709 dir = path.substr (0, slash+1);
2711 /* '-' is not a legal character for the NAME part of the path */
2713 if ((dash = path.find_last_of ('-')) == string::npos) {
2717 prefix = path.substr (slash+1, dash-(slash+1));
2722 path += new_legalized;
2723 path += ".wav"; /* XXX gag me with a spoon */
2727 /* non-destructive file sources have a name of the form:
2729 /path/to/NAME-nnnnn(%[LR])?.wav
2731 the task here is to replace NAME with the new name.
2734 /* find last slash */
2738 string::size_type slash;
2739 string::size_type dash;
2741 if ((slash = path.find_last_of ('/')) == string::npos) {
2745 dir = path.substr (0, slash+1);
2747 /* '-' is not a legal character for the NAME part of the path */
2749 if ((dash = path.find_last_of ('-')) == string::npos) {
2753 suffix = path.substr (dash);
2756 path += new_legalized;
2764 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2768 char buf[PATH_MAX+1];
2769 const uint32_t limit = 10000;
2773 legalized = legalize_for_path (name);
2775 /* find a "version" of the file name that doesn't exist in
2776 any of the possible directories.
2779 for (cnt = (destructive ? destructive_index + 1 : 1); cnt <= limit; ++cnt) {
2781 vector<space_and_path>::iterator i;
2782 uint32_t existing = 0;
2784 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2789 spath += tape_dir_name;
2791 spath += sound_dir_name;
2796 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2797 } else if (nchan == 2) {
2799 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2801 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2803 } else if (nchan < 26) {
2804 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2806 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2814 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2815 } else if (nchan == 2) {
2817 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2819 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2821 } else if (nchan < 26) {
2822 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2824 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2828 if (access (buf, F_OK) == 0) {
2833 if (existing == 0) {
2838 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2839 throw failed_constructor();
2843 /* we now have a unique name for the file, but figure out where to
2850 spath = tape_dir ();
2852 spath = discover_best_sound_dir ();
2855 string::size_type pos = foo.find_last_of ('/');
2857 if (pos == string::npos) {
2860 spath += foo.substr (pos + 1);
2867 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2869 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2871 /* this might throw failed_constructor(), which is OK */
2874 return new DestructiveFileSource (spath, frame_rate());
2876 return new FileSource (spath, frame_rate());
2880 /* Playlist management */
2883 Session::get_playlist (string name)
2887 if ((ret = playlist_by_name (name)) == 0) {
2888 ret = new AudioPlaylist (*this, name);
2895 Session::playlist_by_name (string name)
2897 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2898 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2899 if ((*i)->name() == name) {
2903 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2904 if ((*i)->name() == name) {
2912 Session::add_playlist (Playlist* playlist)
2914 if (playlist->hidden()) {
2919 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2920 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2921 playlists.insert (playlists.begin(), playlist);
2923 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2924 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2930 PlaylistAdded (playlist); /* EMIT SIGNAL */
2934 Session::track_playlist (Playlist* pl, bool inuse)
2936 PlaylistList::iterator x;
2939 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2942 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2944 unused_playlists.insert (pl);
2946 if ((x = playlists.find (pl)) != playlists.end()) {
2947 playlists.erase (x);
2952 //cerr << "shifting playlist to used: " << pl->name() << endl;
2954 playlists.insert (pl);
2956 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2957 unused_playlists.erase (x);
2964 Session::remove_playlist (Playlist* playlist)
2966 if (_state_of_the_state & Deletion) {
2971 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2972 // cerr << "removing playlist: " << playlist->name() << endl;
2974 PlaylistList::iterator i;
2976 i = find (playlists.begin(), playlists.end(), playlist);
2978 if (i != playlists.end()) {
2979 playlists.erase (i);
2982 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2983 if (i != unused_playlists.end()) {
2984 unused_playlists.erase (i);
2991 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2995 Session::set_audition (AudioRegion* r)
2997 pending_audition_region = r;
2998 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2999 schedule_butler_transport_work ();
3003 Session::non_realtime_set_audition ()
3005 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3006 auditioner->audition_current_playlist ();
3007 } else if (pending_audition_region) {
3008 auditioner->audition_region (*pending_audition_region);
3010 pending_audition_region = 0;
3011 AuditionActive (true); /* EMIT SIGNAL */
3015 Session::audition_playlist ()
3017 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3018 ev->set_ptr ((void*) 0xfeedface);
3023 Session::audition_region (AudioRegion& r)
3025 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3031 Session::cancel_audition ()
3033 if (auditioner->active()) {
3034 auditioner->cancel_audition ();
3035 AuditionActive (false); /* EMIT SIGNAL */
3040 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3042 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3046 Session::remove_empty_sounds ()
3049 PathScanner scanner;
3054 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3056 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3058 if (FileSource::is_empty (*(*i))) {
3060 unlink ((*i)->c_str());
3062 string peak_path = peak_path_from_audio_path (**i);
3063 unlink (peak_path.c_str());
3069 delete possible_audiofiles;
3073 Session::is_auditioning () const
3075 /* can be called before we have an auditioner object */
3077 return auditioner->active();
3084 Session::set_all_solo (bool yn)
3087 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3089 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3090 if (!(*i)->hidden()) {
3091 (*i)->set_solo (yn, this);
3100 Session::set_all_mute (bool yn)
3103 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3105 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3106 if (!(*i)->hidden()) {
3107 (*i)->set_mute (yn, this);
3116 Session::n_diskstreams () const
3118 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3121 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3122 if (!(*i)->hidden()) {
3130 Session::foreach_diskstream (void (DiskStream::*func)(void))
3132 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3133 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3134 if (!(*i)->hidden()) {
3141 Session::graph_reordered ()
3143 /* don't do this stuff if we are setting up connections
3144 from a set_state() call.
3147 if (_state_of_the_state & InitialConnecting) {
3151 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3152 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3156 /* force all diskstreams to update their capture offset values to
3157 reflect any changes in latencies within the graph.
3160 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3161 (*i)->set_capture_offset ();
3166 Session::record_disenable_all ()
3168 record_enable_change_all (false);
3172 Session::record_enable_all ()
3174 record_enable_change_all (true);
3178 Session::record_enable_change_all (bool yn)
3180 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3182 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3185 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3186 at->set_record_enable (yn, this);
3190 /* since we don't keep rec-enable state, don't mark session dirty */
3194 Session::add_redirect (Redirect* redirect)
3198 PortInsert* port_insert;
3199 PluginInsert* plugin_insert;
3201 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3202 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3203 _port_inserts.insert (_port_inserts.begin(), port_insert);
3204 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3205 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3207 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3210 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3211 _sends.insert (_sends.begin(), send);
3213 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3217 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3223 Session::remove_redirect (Redirect* redirect)
3227 PortInsert* port_insert;
3228 PluginInsert* plugin_insert;
3230 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3231 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3232 _port_inserts.remove (port_insert);
3233 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3234 _plugin_inserts.remove (plugin_insert);
3236 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3239 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3240 _sends.remove (send);
3242 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3250 Session::available_capture_duration ()
3252 const double scale = 4096.0 / sizeof (Sample);
3254 if (_total_free_4k_blocks * scale > (double) max_frames) {
3258 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3262 Session::add_connection (ARDOUR::Connection* connection)
3265 LockMonitor (connection_lock, __LINE__, __FILE__);
3266 _connections.push_back (connection);
3269 ConnectionAdded (connection); /* EMIT SIGNAL */
3275 Session::remove_connection (ARDOUR::Connection* connection)
3277 bool removed = false;
3280 LockMonitor (connection_lock, __LINE__, __FILE__);
3281 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3283 if (i != _connections.end()) {
3284 _connections.erase (i);
3290 ConnectionRemoved (connection); /* EMIT SIGNAL */
3296 ARDOUR::Connection *
3297 Session::connection_by_name (string name) const
3299 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3301 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3302 if ((*i)->name() == name) {
3311 Session::set_edit_mode (EditMode mode)
3316 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3318 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3319 (*i)->set_edit_mode (mode);
3324 ControlChanged (EditingMode); /* EMIT SIGNAL */
3328 Session::tempo_map_changed (Change ignored)
3335 Session::ensure_passthru_buffers (uint32_t howmany)
3337 while (howmany > _passthru_buffers.size()) {
3339 #ifdef NO_POSIX_MEMALIGN
3340 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3342 posix_memalign((void **)&p,16,current_block_size * 4);
3344 _passthru_buffers.push_back (p);
3348 #ifdef NO_POSIX_MEMALIGN
3349 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3351 posix_memalign((void **)&p,16,current_block_size * 4);
3353 memset (p, 0, sizeof (Sample) * current_block_size);
3354 _silent_buffers.push_back (p);
3358 #ifdef NO_POSIX_MEMALIGN
3359 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3361 posix_memalign((void **)&p,16,current_block_size * 4);
3363 memset (p, 0, sizeof (Sample) * current_block_size);
3364 _send_buffers.push_back (p);
3367 allocate_pan_automation_buffers (current_block_size, howmany, false);
3371 Session::next_send_name ()
3374 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3379 Session::next_insert_name ()
3382 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3386 /* Named Selection management */
3389 Session::named_selection_by_name (string name)
3391 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3392 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3393 if ((*i)->name == name) {
3401 Session::add_named_selection (NamedSelection* named_selection)
3404 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3405 named_selections.insert (named_selections.begin(), named_selection);
3410 NamedSelectionAdded (); /* EMIT SIGNAL */
3414 Session::remove_named_selection (NamedSelection* named_selection)
3416 bool removed = false;
3419 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3421 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3423 if (i != named_selections.end()) {
3425 named_selections.erase (i);
3432 NamedSelectionRemoved (); /* EMIT SIGNAL */
3437 Session::reset_native_file_format ()
3439 // jlc - WHY take routelock?
3440 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3441 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3443 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3444 (*i)->reset_write_sources (false);
3449 Session::route_name_unique (string n) const
3451 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3453 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3454 if ((*i)->name() == n) {
3463 Session::remove_file_source (FileSource& fs)
3465 return fs.move_to_trash (dead_sound_dir_name);
3469 Session::n_playlists () const
3471 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3472 return playlists.size();
3476 Session::set_solo_model (SoloModel sm)
3478 if (sm != _solo_model) {
3480 ControlChanged (SoloingModel);
3486 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3488 if (!force && howmany <= _npan_buffers) {
3492 if (_pan_automation_buffer) {
3494 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3495 delete [] _pan_automation_buffer[i];
3498 delete [] _pan_automation_buffer;
3501 _pan_automation_buffer = new pan_t*[howmany];
3503 for (uint32_t i = 0; i < howmany; ++i) {
3504 _pan_automation_buffer[i] = new pan_t[nframes];
3507 _npan_buffers = howmany;
3511 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3513 Stateful::add_instant_xml (node, dir);
3514 Config->add_instant_xml (node, get_user_ardour_path());
3518 Session::freeze (InterThreadInfo& itt)
3520 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3522 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3526 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3527 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3538 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3539 InterThreadInfo& itt)
3543 FileSource* fsource;
3545 char buf[PATH_MAX+1];
3548 jack_nframes_t position;
3549 jack_nframes_t this_chunk;
3550 jack_nframes_t to_do;
3551 vector<Sample*> buffers;
3553 const jack_nframes_t chunk_size = (256 * 1024)/4;
3555 atomic_set (&processing_prohibited, 1);
3557 /* call tree *MUST* hold route_lock */
3559 if ((playlist = track.disk_stream().playlist()) == 0) {
3563 /* external redirects will be a problem */
3565 if (track.has_external_redirects()) {
3569 nchans = track.disk_stream().n_channels();
3571 dir = discover_best_sound_dir ();
3573 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3575 for (x = 0; x < 99999; ++x) {
3576 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3577 if (access (buf, F_OK) != 0) {
3583 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3588 fsource = new FileSource (buf, frame_rate());
3591 catch (failed_constructor& err) {
3592 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3596 srcs.push_back(fsource);
3599 /* XXX need to flush all redirects */
3604 /* create a set of reasonably-sized buffers */
3606 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3608 #ifdef NO_POSIX_MEMALIGN
3609 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3611 posix_memalign((void **)&b,16,chunk_size * 4);
3613 buffers.push_back (b);
3616 workbuf = new char[chunk_size * 4];
3618 while (to_do && !itt.cancel) {
3620 this_chunk = min (to_do, chunk_size);
3622 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3627 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3628 if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3633 start += this_chunk;
3634 to_do -= this_chunk;
3636 itt.progress = (float) (1.0 - ((double) to_do / len));
3645 xnow = localtime (&now);
3647 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3648 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3651 /* build peakfile for new source */
3653 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3654 dynamic_cast<FileSource*>(*src)->build_peaks ();
3662 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3663 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3668 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3676 atomic_set (&processing_prohibited, 0);
3684 Session::get_silent_buffers (uint32_t howmany)
3686 for (uint32_t i = 0; i < howmany; ++i) {
3687 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3689 return _silent_buffers;
3693 Session::ntracks () const
3696 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3698 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3699 if (dynamic_cast<AudioTrack*> (*i)) {
3708 Session::nbusses () 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) == 0) {
3723 Session::set_layer_model (LayerModel lm)
3725 if (lm != layer_model) {
3728 ControlChanged (LayeringModel);
3733 Session::set_xfade_model (CrossfadeModel xm)
3735 if (xm != xfade_model) {
3738 ControlChanged (CrossfadingModel);