2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
70 #include <ardour/osc.h>
76 using namespace ARDOUR;
78 using boost::shared_ptr;
80 const char* Session::_template_suffix = X_(".template");
81 const char* Session::_statefile_suffix = X_(".ardour");
82 const char* Session::_pending_suffix = X_(".pending");
83 const char* Session::sound_dir_name = X_("sounds");
84 const char* Session::tape_dir_name = X_("tapes");
85 const char* Session::peak_dir_name = X_("peaks");
86 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 Session::compute_peak_t Session::compute_peak = 0;
89 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
90 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
91 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
93 sigc::signal<int> Session::AskAboutPendingState;
94 sigc::signal<void> Session::SMPTEOffsetChanged;
95 sigc::signal<void> Session::SendFeedback;
99 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
102 char buf[PATH_MAX+1];
106 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
107 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
113 /* check to see if it exists, and what it is */
115 if (stat (str.c_str(), &statbuf)) {
116 if (errno == ENOENT) {
119 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
127 /* it exists, so it must either be the name
128 of the directory, or the name of the statefile
132 if (S_ISDIR (statbuf.st_mode)) {
134 string::size_type slash = str.find_last_of ('/');
136 if (slash == string::npos) {
138 /* a subdirectory of cwd, so statefile should be ... */
144 tmp += _statefile_suffix;
148 if (stat (tmp.c_str(), &statbuf)) {
149 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
159 /* some directory someplace in the filesystem.
160 the snapshot name is the directory name
165 snapshot = str.substr (slash+1);
169 } else if (S_ISREG (statbuf.st_mode)) {
171 string::size_type slash = str.find_last_of ('/');
172 string::size_type suffix;
174 /* remove the suffix */
176 if (slash != string::npos) {
177 snapshot = str.substr (slash+1);
182 suffix = snapshot.find (_statefile_suffix);
184 if (suffix == string::npos) {
185 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
191 snapshot = snapshot.substr (0, suffix);
193 if (slash == string::npos) {
195 /* we must be in the directory where the
196 statefile lives. get it using cwd().
199 char cwd[PATH_MAX+1];
201 if (getcwd (cwd, sizeof (cwd)) == 0) {
202 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
211 /* full path to the statefile */
213 path = str.substr (0, slash);
218 /* what type of file is it? */
219 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
225 /* its the name of a new directory. get the name
229 string::size_type slash = str.find_last_of ('/');
231 if (slash == string::npos) {
233 /* no slash, just use the name, but clean it up */
235 path = legalize_for_path (str);
241 snapshot = str.substr (slash+1);
248 Session::Session (AudioEngine &eng,
250 string snapshot_name,
251 string* mix_template)
254 _mmc_port (default_mmc_port),
255 _mtc_port (default_mtc_port),
256 _midi_port (default_midi_port),
257 pending_events (2048),
258 midi_requests (128), // the size of this should match the midi request pool size
259 diskstreams (new DiskstreamList),
260 routes (new RouteList),
261 auditioner ((Auditioner*) 0),
267 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
269 n_physical_outputs = _engine.n_physical_outputs();
270 n_physical_inputs = _engine.n_physical_inputs();
272 first_stage_init (fullpath, snapshot_name);
274 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
275 throw failed_constructor ();
278 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions(_name, _path);
284 bool was_dirty = dirty();
286 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
289 DirtyChanged (); /* EMIT SIGNAL */
293 Session::Session (AudioEngine &eng,
295 string snapshot_name,
296 AutoConnectOption input_ac,
297 AutoConnectOption output_ac,
298 uint32_t control_out_channels,
299 uint32_t master_out_channels,
300 uint32_t requested_physical_in,
301 uint32_t requested_physical_out,
302 jack_nframes_t initial_length)
305 _mmc_port (default_mmc_port),
306 _mtc_port (default_mtc_port),
307 _midi_port (default_midi_port),
308 pending_events (2048),
310 diskstreams (new DiskstreamList),
311 routes (new RouteList),
317 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
319 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
320 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
322 first_stage_init (fullpath, snapshot_name);
324 if (create (new_session, 0, initial_length)) {
325 throw failed_constructor ();
328 if (control_out_channels) {
329 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
334 if (master_out_channels) {
335 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
339 /* prohibit auto-connect to master, because there isn't one */
340 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
343 input_auto_connect = input_ac;
344 output_auto_connect = output_ac;
346 if (second_stage_init (new_session)) {
347 throw failed_constructor ();
350 store_recent_sessions(_name, _path);
352 bool was_dirty = dirty ();
354 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
357 DirtyChanged (); /* EMIT SIGNAL */
363 /* if we got to here, leaving pending capture state around
367 remove_pending_capture_state ();
369 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
370 _engine.remove_session ();
372 going_away (); /* EMIT SIGNAL */
374 terminate_butler_thread ();
375 terminate_midi_thread ();
377 if (click_data && click_data != default_click) {
378 delete [] click_data;
381 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
382 delete [] click_emphasis_data;
387 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
391 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
395 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
399 AudioDiskstream::free_working_buffers();
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 */
447 RCUWriter<RouteList> writer (routes);
448 boost::shared_ptr<RouteList> r = writer.get_copy ();
449 for (RouteList::iterator i = r->begin(); i != r->end(); ) {
450 RouteList::iterator tmp;
453 cerr << "BEFORE: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
454 (*i)->drop_references ();
455 cerr << "AFTER: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
459 /* writer goes out of scope and updates master */
464 #ifdef TRACK_DESTRUCTION
465 cerr << "delete diskstreams\n";
466 #endif /* TRACK_DESTRUCTION */
468 RCUWriter<DiskstreamList> dwriter (diskstreams);
469 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
470 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
471 DiskstreamList::iterator tmp;
476 (*i)->drop_references ();
482 diskstreams.flush ();
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete audio sources\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
488 AudioSourceList::iterator tmp;
498 #ifdef TRACK_DESTRUCTION
499 cerr << "delete mix groups\n";
500 #endif /* TRACK_DESTRUCTION */
501 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
502 list<RouteGroup*>::iterator tmp;
512 #ifdef TRACK_DESTRUCTION
513 cerr << "delete edit groups\n";
514 #endif /* TRACK_DESTRUCTION */
515 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
516 list<RouteGroup*>::iterator tmp;
526 #ifdef TRACK_DESTRUCTION
527 cerr << "delete connections\n";
528 #endif /* TRACK_DESTRUCTION */
529 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
530 ConnectionList::iterator tmp;
540 if (butler_mixdown_buffer) {
541 delete [] butler_mixdown_buffer;
544 if (butler_gain_buffer) {
545 delete [] butler_gain_buffer;
548 Crossfade::set_buffer_size (0);
560 Session::set_worst_io_latencies ()
562 _worst_output_latency = 0;
563 _worst_input_latency = 0;
565 if (!_engine.connected()) {
569 boost::shared_ptr<RouteList> r = routes.reader ();
571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
572 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
573 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
578 Session::when_engine_running ()
580 string first_physical_output;
582 /* we don't want to run execute this again */
584 first_time_running.disconnect ();
586 set_block_size (_engine.frames_per_cycle());
587 set_frame_rate (_engine.frame_rate());
589 /* every time we reconnect, recompute worst case output latencies */
591 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
593 if (synced_to_jack()) {
594 _engine.transport_stop ();
597 if (Config->get_jack_time_master()) {
598 _engine.transport_locate (_transport_frame);
606 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
608 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
610 /* existing state for Click */
612 if (_click_io->set_state (*child->children().front()) == 0) {
614 _clicking = click_requested;
618 error << _("could not setup Click I/O") << endmsg;
624 /* default state for Click */
626 first_physical_output = _engine.get_nth_physical_output (0);
628 if (first_physical_output.length()) {
629 if (_click_io->add_output_port (first_physical_output, this)) {
630 // relax, even though its an error
632 _clicking = click_requested;
638 catch (failed_constructor& err) {
639 error << _("cannot setup Click I/O") << endmsg;
642 set_worst_io_latencies ();
645 ControlChanged (Clicking); /* EMIT SIGNAL */
648 if (auditioner == 0) {
650 /* we delay creating the auditioner till now because
651 it makes its own connections to ports named
652 in the ARDOUR_RC config file. the engine has
653 to be running for this to work.
657 auditioner.reset (new Auditioner (*this));
660 catch (failed_constructor& err) {
661 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
665 /* Create a set of Connection objects that map
666 to the physical outputs currently available
671 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
673 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
675 Connection* c = new OutputConnection (buf, true);
678 c->add_connection (0, _engine.get_nth_physical_output (np));
683 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
685 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
687 Connection* c = new InputConnection (buf, true);
690 c->add_connection (0, _engine.get_nth_physical_input (np));
697 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
699 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
701 Connection* c = new OutputConnection (buf, true);
705 c->add_connection (0, _engine.get_nth_physical_output (np));
706 c->add_connection (1, _engine.get_nth_physical_output (np+1));
711 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
713 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
715 Connection* c = new InputConnection (buf, true);
719 c->add_connection (0, _engine.get_nth_physical_input (np));
720 c->add_connection (1, _engine.get_nth_physical_input (np+1));
729 /* create master/control ports */
734 /* force the master to ignore any later call to this */
736 if (_master_out->pending_state_node) {
737 _master_out->ports_became_legal();
740 /* no panner resets till we are through */
742 _master_out->defer_pan_reset ();
744 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
745 if (_master_out->add_input_port ("", this)) {
746 error << _("cannot setup master inputs")
752 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
753 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
754 error << _("cannot setup master outputs")
761 _master_out->allow_pan_reset ();
765 Connection* c = new OutputConnection (_("Master Out"), true);
767 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
769 c->add_connection ((int) n, _master_out->input(n)->name());
776 /* catch up on send+insert cnts */
780 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
783 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
784 if (id > insert_cnt) {
792 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
795 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
802 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
804 /* hook us up to the engine */
806 _engine.set_session (this);
811 osc->set_session (*this);
814 _state_of_the_state = Clean;
816 DirtyChanged (); /* EMIT SIGNAL */
820 Session::hookup_io ()
822 /* stop graph reordering notifications from
823 causing resorts, etc.
826 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
828 /* Tell all IO objects to create their ports */
835 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
836 if (_control_out->add_input_port ("", this)) {
837 error << _("cannot setup control inputs")
843 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
844 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
845 error << _("cannot set up master outputs")
853 /* Tell all IO objects to connect themselves together */
855 IO::enable_connecting ();
857 /* Now reset all panners */
859 IO::reset_panners ();
861 /* Anyone who cares about input state, wake up and do something */
863 IOConnectionsComplete (); /* EMIT SIGNAL */
865 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
867 /* now handle the whole enchilada as if it was one
873 /* update mixer solo state */
879 Session::playlist_length_changed (Playlist* pl)
881 /* we can't just increase end_location->end() if pl->get_maximum_extent()
882 if larger. if the playlist used to be the longest playlist,
883 and its now shorter, we have to decrease end_location->end(). hence,
884 we have to iterate over all diskstreams and check the
885 playlists currently in use.
891 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
895 if ((playlist = dstream->playlist()) != 0) {
896 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
899 /* see comment in playlist_length_changed () */
904 Session::record_enabling_legal () const
906 /* this used to be in here, but survey says.... we don't need to restrict it */
907 // if (record_status() == Recording) {
918 Session::set_auto_play (bool yn)
920 if (auto_play != yn) {
923 ControlChanged (AutoPlay);
928 Session::set_auto_return (bool yn)
930 if (auto_return != yn) {
933 ControlChanged (AutoReturn);
938 Session::set_crossfades_active (bool yn)
940 if (crossfades_active != yn) {
941 crossfades_active = yn;
943 ControlChanged (CrossFadesActive);
948 Session::set_do_not_record_plugins (bool yn)
950 if (do_not_record_plugins != yn) {
951 do_not_record_plugins = yn;
953 ControlChanged (RecordingPlugins);
958 Session::set_auto_input (bool yn)
960 if (auto_input != yn) {
963 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
964 /* auto-input only makes a difference if we're rolling */
966 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
968 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
969 if ((*i)->record_enabled ()) {
970 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
971 (*i)->monitor_input (!auto_input);
977 ControlChanged (AutoInput);
982 Session::reset_input_monitor_state ()
984 if (transport_rolling()) {
986 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
988 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
989 if ((*i)->record_enabled ()) {
990 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
991 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
995 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
997 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
998 if ((*i)->record_enabled ()) {
999 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1000 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1008 Session::set_input_auto_connect (bool yn)
1011 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1013 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1019 Session::get_input_auto_connect () const
1021 return (input_auto_connect & AutoConnectPhysical);
1025 Session::set_output_auto_connect (AutoConnectOption aco)
1027 output_auto_connect = aco;
1032 Session::auto_punch_start_changed (Location* location)
1034 replace_event (Event::PunchIn, location->start());
1036 if (get_record_enabled() && get_punch_in()) {
1037 /* capture start has been changed, so save new pending state */
1038 save_state ("", true);
1043 Session::auto_punch_end_changed (Location* location)
1045 jack_nframes_t when_to_stop = location->end();
1046 // when_to_stop += _worst_output_latency + _worst_input_latency;
1047 replace_event (Event::PunchOut, when_to_stop);
1051 Session::auto_punch_changed (Location* location)
1053 jack_nframes_t when_to_stop = location->end();
1055 replace_event (Event::PunchIn, location->start());
1056 //when_to_stop += _worst_output_latency + _worst_input_latency;
1057 replace_event (Event::PunchOut, when_to_stop);
1061 Session::auto_loop_changed (Location* location)
1063 replace_event (Event::AutoLoop, location->end(), location->start());
1065 if (transport_rolling() && get_auto_loop()) {
1067 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1069 if (_transport_frame > location->end()) {
1070 // relocate to beginning of loop
1071 clear_events (Event::LocateRoll);
1073 request_locate (location->start(), true);
1076 else if (seamless_loop && !loop_changing) {
1078 // schedule a locate-roll to refill the diskstreams at the
1079 // previous loop end
1080 loop_changing = true;
1082 if (location->end() > last_loopend) {
1083 clear_events (Event::LocateRoll);
1084 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1091 last_loopend = location->end();
1096 Session::set_auto_punch_location (Location* location)
1100 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1101 auto_punch_start_changed_connection.disconnect();
1102 auto_punch_end_changed_connection.disconnect();
1103 auto_punch_changed_connection.disconnect();
1104 existing->set_auto_punch (false, this);
1105 remove_event (existing->start(), Event::PunchIn);
1106 clear_events (Event::PunchOut);
1107 auto_punch_location_changed (0);
1112 if (location == 0) {
1116 if (location->end() <= location->start()) {
1117 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1121 auto_punch_start_changed_connection.disconnect();
1122 auto_punch_end_changed_connection.disconnect();
1123 auto_punch_changed_connection.disconnect();
1125 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1126 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1127 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1129 location->set_auto_punch (true, this);
1130 auto_punch_location_changed (location);
1134 Session::set_punch_in (bool yn)
1136 if (punch_in == yn) {
1142 if ((location = _locations.auto_punch_location()) != 0) {
1143 if ((punch_in = yn) == true) {
1144 replace_event (Event::PunchIn, location->start());
1146 remove_event (location->start(), Event::PunchIn);
1151 ControlChanged (PunchIn); /* EMIT SIGNAL */
1155 Session::set_punch_out (bool yn)
1157 if (punch_out == yn) {
1163 if ((location = _locations.auto_punch_location()) != 0) {
1164 if ((punch_out = yn) == true) {
1165 replace_event (Event::PunchOut, location->end());
1167 clear_events (Event::PunchOut);
1172 ControlChanged (PunchOut); /* EMIT SIGNAL */
1176 Session::set_auto_loop_location (Location* location)
1180 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1181 auto_loop_start_changed_connection.disconnect();
1182 auto_loop_end_changed_connection.disconnect();
1183 auto_loop_changed_connection.disconnect();
1184 existing->set_auto_loop (false, this);
1185 remove_event (existing->end(), Event::AutoLoop);
1186 auto_loop_location_changed (0);
1191 if (location == 0) {
1195 if (location->end() <= location->start()) {
1196 error << _("Session: you can't use a mark for auto loop") << endmsg;
1200 last_loopend = location->end();
1202 auto_loop_start_changed_connection.disconnect();
1203 auto_loop_end_changed_connection.disconnect();
1204 auto_loop_changed_connection.disconnect();
1206 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1207 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1208 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1210 location->set_auto_loop (true, this);
1211 auto_loop_location_changed (location);
1215 Session::locations_added (Location* ignored)
1221 Session::locations_changed ()
1223 _locations.apply (*this, &Session::handle_locations_changed);
1227 Session::handle_locations_changed (Locations::LocationList& locations)
1229 Locations::LocationList::iterator i;
1231 bool set_loop = false;
1232 bool set_punch = false;
1234 for (i = locations.begin(); i != locations.end(); ++i) {
1238 if (location->is_auto_punch()) {
1239 set_auto_punch_location (location);
1242 if (location->is_auto_loop()) {
1243 set_auto_loop_location (location);
1250 set_auto_loop_location (0);
1253 set_auto_punch_location (0);
1260 Session::enable_record ()
1262 /* XXX really atomic compare+swap here */
1263 if (g_atomic_int_get (&_record_status) != Recording) {
1264 g_atomic_int_set (&_record_status, Recording);
1265 _last_record_location = _transport_frame;
1266 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1268 if (Config->get_use_hardware_monitoring() && auto_input) {
1269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1271 if ((*i)->record_enabled ()) {
1272 (*i)->monitor_input (true);
1277 RecordStateChanged ();
1282 Session::disable_record (bool rt_context, bool force)
1286 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1288 if (!Config->get_latched_record_enable () || force) {
1289 g_atomic_int_set (&_record_status, Disabled);
1291 if (rs == Recording) {
1292 g_atomic_int_set (&_record_status, Enabled);
1296 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1298 if (Config->get_use_hardware_monitoring() && auto_input) {
1299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1302 if ((*i)->record_enabled ()) {
1303 (*i)->monitor_input (false);
1308 RecordStateChanged (); /* emit signal */
1311 remove_pending_capture_state ();
1317 Session::step_back_from_record ()
1319 g_atomic_int_set (&_record_status, Enabled);
1321 if (Config->get_use_hardware_monitoring()) {
1322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1325 if (auto_input && (*i)->record_enabled ()) {
1326 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1327 (*i)->monitor_input (false);
1334 Session::maybe_enable_record ()
1336 g_atomic_int_set (&_record_status, Enabled);
1338 /* XXX this save should really happen in another thread. its needed so that
1339 pending capture state can be recovered if we crash.
1342 save_state ("", true);
1344 if (_transport_speed) {
1349 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1350 RecordStateChanged (); /* EMIT SIGNAL */
1357 Session::audible_frame () const
1360 jack_nframes_t offset;
1363 /* the first of these two possible settings for "offset"
1364 mean that the audible frame is stationary until
1365 audio emerges from the latency compensation
1368 the second means that the audible frame is stationary
1369 until audio would emerge from a physical port
1370 in the absence of any plugin latency compensation
1373 offset = _worst_output_latency;
1375 if (offset > current_block_size) {
1376 offset -= current_block_size;
1378 /* XXX is this correct? if we have no external
1379 physical connections and everything is internal
1380 then surely this is zero? still, how
1381 likely is that anyway?
1383 offset = current_block_size;
1386 if (synced_to_jack()) {
1387 tf = _engine.transport_frame();
1389 tf = _transport_frame;
1392 if (_transport_speed == 0) {
1402 if (!non_realtime_work_pending()) {
1406 /* take latency into account */
1415 Session::set_frame_rate (jack_nframes_t frames_per_second)
1417 /** \fn void Session::set_frame_size(jack_nframes_t)
1418 the AudioEngine object that calls this guarantees
1419 that it will not be called while we are also in
1420 ::process(). Its fine to do things that block
1424 _current_frame_rate = frames_per_second;
1425 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1427 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1429 // XXX we need some equivalent to this, somehow
1430 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1434 /* XXX need to reset/reinstantiate all LADSPA plugins */
1438 Session::set_block_size (jack_nframes_t nframes)
1440 /* the AudioEngine guarantees
1441 that it will not be called while we are also in
1442 ::process(). It is therefore fine to do things that block
1447 vector<Sample*>::iterator i;
1450 current_block_size = nframes;
1452 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1456 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1460 _passthru_buffers.clear ();
1461 _silent_buffers.clear ();
1463 ensure_passthru_buffers (np);
1465 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1469 #ifdef NO_POSIX_MEMALIGN
1470 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1472 posix_memalign((void **)&buf,16,current_block_size * 4);
1476 memset (*i, 0, sizeof (Sample) * current_block_size);
1480 if (_gain_automation_buffer) {
1481 delete [] _gain_automation_buffer;
1483 _gain_automation_buffer = new gain_t[nframes];
1485 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1487 boost::shared_ptr<RouteList> r = routes.reader ();
1489 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1490 (*i)->set_block_size (nframes);
1493 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1494 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1495 (*i)->set_block_size (nframes);
1498 set_worst_io_latencies ();
1503 Session::set_default_fade (float steepness, float fade_msecs)
1506 jack_nframes_t fade_frames;
1508 /* Don't allow fade of less 1 frame */
1510 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1517 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1521 default_fade_msecs = fade_msecs;
1522 default_fade_steepness = steepness;
1525 // jlc, WTF is this!
1526 Glib::RWLock::ReaderLock lm (route_lock);
1527 AudioRegion::set_default_fade (steepness, fade_frames);
1532 /* XXX have to do this at some point */
1533 /* foreach region using default fade, reset, then
1534 refill_all_diskstream_buffers ();
1539 struct RouteSorter {
1540 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1541 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1543 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1546 if (r1->fed_by.empty()) {
1547 if (r2->fed_by.empty()) {
1548 /* no ardour-based connections inbound to either route. just use signal order */
1549 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1551 /* r2 has connections, r1 does not; run r1 early */
1555 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1562 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1564 shared_ptr<Route> r2;
1566 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1567 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1571 /* make a copy of the existing list of routes that feed r1 */
1573 set<shared_ptr<Route> > existing = r1->fed_by;
1575 /* for each route that feeds r1, recurse, marking it as feeding
1579 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1582 /* r2 is a route that feeds r1 which somehow feeds base. mark
1583 base as being fed by r2
1586 rbase->fed_by.insert (r2);
1590 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1594 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1598 /* now recurse, so that we can mark base as being fed by
1599 all routes that feed r2
1602 trace_terminal (r2, rbase);
1609 Session::resort_routes ()
1611 /* don't do anything here with signals emitted
1612 by Routes while we are being destroyed.
1615 if (_state_of_the_state & Deletion) {
1622 RCUWriter<RouteList> writer (routes);
1623 shared_ptr<RouteList> r = writer.get_copy ();
1624 resort_routes_using (r);
1625 /* writer goes out of scope and forces update */
1630 Session::resort_routes_using (shared_ptr<RouteList> r)
1632 RouteList::iterator i, j;
1634 for (i = r->begin(); i != r->end(); ++i) {
1636 (*i)->fed_by.clear ();
1638 for (j = r->begin(); j != r->end(); ++j) {
1640 /* although routes can feed themselves, it will
1641 cause an endless recursive descent if we
1642 detect it. so don't bother checking for
1650 if ((*j)->feeds (*i)) {
1651 (*i)->fed_by.insert (*j);
1656 for (i = r->begin(); i != r->end(); ++i) {
1657 trace_terminal (*i, *i);
1664 cerr << "finished route resort\n";
1666 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1667 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1674 shared_ptr<AudioTrack>
1675 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1677 char track_name[32];
1679 uint32_t channels_used = 0;
1681 uint32_t nphysical_in;
1682 uint32_t nphysical_out;
1684 /* count existing audio tracks */
1687 shared_ptr<RouteList> r = routes.reader ();
1689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1690 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1691 if (!(*i)->hidden()) {
1693 channels_used += (*i)->n_inputs();
1699 /* check for duplicate route names, since we might have pre-existing
1700 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1701 save, close,restart,add new route - first named route is now
1706 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1707 if (route_by_name (track_name) == 0) {
1712 } while (n < (UINT_MAX-1));
1714 if (input_auto_connect & AutoConnectPhysical) {
1715 nphysical_in = n_physical_inputs;
1720 if (output_auto_connect & AutoConnectPhysical) {
1721 nphysical_out = n_physical_outputs;
1727 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1729 if (track->ensure_io (input_channels, output_channels, false, this)) {
1730 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1731 input_channels, output_channels)
1736 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1740 if (input_auto_connect & AutoConnectPhysical) {
1741 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1744 if (port.length() && track->connect_input (track->input (x), port, this)) {
1750 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1754 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1755 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1756 } else if (output_auto_connect & AutoConnectMaster) {
1758 port = _master_out->input (x%_master_out->n_inputs())->name();
1762 if (port.length() && track->connect_output (track->output (x), port, this)) {
1768 vector<string> cports;
1769 uint32_t ni = _control_out->n_inputs();
1771 for (n = 0; n < ni; ++n) {
1772 cports.push_back (_control_out->input(n)->name());
1775 track->set_control_outs (cports);
1778 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1782 track->set_remote_control_id (ntracks());
1786 catch (failed_constructor &err) {
1787 error << _("Session: could not create new audio track.") << endmsg;
1788 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1793 Session::new_audio_route (int input_channels, int output_channels)
1799 /* count existing audio busses */
1802 shared_ptr<RouteList> r = routes.reader ();
1804 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1805 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1806 if (!(*i)->hidden()) {
1814 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1815 if (route_by_name (bus_name) == 0) {
1820 } while (n < (UINT_MAX-1));
1823 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1825 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1826 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1827 input_channels, output_channels)
1831 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1835 if (input_auto_connect & AutoConnectPhysical) {
1836 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1839 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1844 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1848 if (output_auto_connect & AutoConnectPhysical) {
1849 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1850 } else if (output_auto_connect & AutoConnectMaster) {
1852 port = _master_out->input (x%_master_out->n_inputs())->name();
1856 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1862 vector<string> cports;
1863 uint32_t ni = _control_out->n_inputs();
1865 for (uint32_t n = 0; n < ni; ++n) {
1866 cports.push_back (_control_out->input(n)->name());
1868 bus->set_control_outs (cports);
1875 catch (failed_constructor &err) {
1876 error << _("Session: could not create new audio route.") << endmsg;
1877 return shared_ptr<Route> ((Route*) 0);
1882 Session::add_route (boost::shared_ptr<Route> route)
1885 RCUWriter<RouteList> writer (routes);
1886 shared_ptr<RouteList> r = writer.get_copy ();
1887 r->push_front (route);
1888 resort_routes_using (r);
1891 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1892 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1893 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1894 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1896 if (route->master()) {
1897 _master_out = route;
1900 if (route->control()) {
1901 _control_out = route;
1905 save_state (_current_snapshot_name);
1907 RouteAdded (route); /* EMIT SIGNAL */
1911 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1913 /* need to do this in case we're rolling at the time, to prevent false underruns */
1914 dstream->do_refill_with_alloc();
1917 RCUWriter<DiskstreamList> writer (diskstreams);
1918 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1919 ds->push_back (dstream);
1922 dstream->set_block_size (current_block_size);
1924 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1925 /* this will connect to future changes, and check the current length */
1926 diskstream_playlist_changed (dstream);
1928 dstream->prepare ();
1931 save_state (_current_snapshot_name);
1935 Session::remove_route (shared_ptr<Route> route)
1938 RCUWriter<RouteList> writer (routes);
1939 shared_ptr<RouteList> rs = writer.get_copy ();
1942 /* deleting the master out seems like a dumb
1943 idea, but its more of a UI policy issue
1947 if (route == _master_out) {
1948 _master_out = shared_ptr<Route> ((Route*) 0);
1951 if (route == _control_out) {
1952 _control_out = shared_ptr<Route> ((Route*) 0);
1954 /* cancel control outs for all routes */
1956 vector<string> empty;
1958 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1959 (*r)->set_control_outs (empty);
1963 update_route_solo_state ();
1965 /* writer goes out of scope, forces route list update */
1968 // FIXME: audio specific
1970 boost::shared_ptr<AudioDiskstream> ds;
1972 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1973 ds = at->audio_diskstream();
1979 RCUWriter<DiskstreamList> dsl (diskstreams);
1980 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1985 find_current_end ();
1987 update_latency_compensation (false, false);
1990 /* XXX should we disconnect from the Route's signals ? */
1992 save_state (_current_snapshot_name);
1994 /* try to cause everyone to drop their references */
1996 route->drop_references ();
2000 Session::route_mute_changed (void* src)
2006 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2008 if (solo_update_disabled) {
2015 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2017 shared_ptr<RouteList> r = routes.reader ();
2019 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2021 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2025 /* don't mess with busses */
2027 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2033 /* don't mess with tracks */
2035 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2040 if ((*i) != route &&
2041 ((*i)->mix_group () == 0 ||
2042 (*i)->mix_group () != route->mix_group () ||
2043 !route->mix_group ()->is_active())) {
2045 if ((*i)->soloed()) {
2047 /* if its already soloed, and solo latching is enabled,
2048 then leave it as it is.
2051 if (_solo_latched) {
2058 solo_update_disabled = true;
2059 (*i)->set_solo (false, src);
2060 solo_update_disabled = false;
2064 bool something_soloed = false;
2065 bool same_thing_soloed = false;
2066 bool signal = false;
2068 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2069 if ((*i)->soloed()) {
2070 something_soloed = true;
2071 if (dynamic_cast<AudioTrack*>((*i).get())) {
2073 same_thing_soloed = true;
2078 same_thing_soloed = true;
2086 if (something_soloed != currently_soloing) {
2088 currently_soloing = something_soloed;
2091 modify_solo_mute (is_track, same_thing_soloed);
2094 SoloActive (currently_soloing);
2101 Session::set_solo_latched (bool yn)
2103 if (yn != _solo_latched) {
2106 ControlChanged (SoloLatch);
2111 Session::update_route_solo_state ()
2114 bool is_track = false;
2115 bool signal = false;
2117 /* caller must hold RouteLock */
2119 /* this is where we actually implement solo by changing
2120 the solo mute setting of each track.
2123 shared_ptr<RouteList> r = routes.reader ();
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126 if ((*i)->soloed()) {
2128 if (dynamic_cast<AudioTrack*>((*i).get())) {
2135 if (mute != currently_soloing) {
2137 currently_soloing = mute;
2140 if (!is_track && !mute) {
2142 /* nothing is soloed */
2144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2145 (*i)->set_solo_mute (false);
2155 modify_solo_mute (is_track, mute);
2158 SoloActive (currently_soloing);
2163 Session::modify_solo_mute (bool is_track, bool mute)
2165 shared_ptr<RouteList> r = routes.reader ();
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2171 /* only alter track solo mute */
2173 if (dynamic_cast<AudioTrack*>((*i).get())) {
2174 if ((*i)->soloed()) {
2175 (*i)->set_solo_mute (!mute);
2177 (*i)->set_solo_mute (mute);
2183 /* only alter bus solo mute */
2185 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2187 if ((*i)->soloed()) {
2189 (*i)->set_solo_mute (false);
2193 /* don't mute master or control outs
2194 in response to another bus solo
2197 if ((*i) != _master_out &&
2198 (*i) != _control_out) {
2199 (*i)->set_solo_mute (mute);
2210 Session::catch_up_on_solo ()
2212 /* this is called after set_state() to catch the full solo
2213 state, which can't be correctly determined on a per-route
2214 basis, but needs the global overview that only the session
2217 update_route_solo_state();
2221 Session::route_by_name (string name)
2223 shared_ptr<RouteList> r = routes.reader ();
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if ((*i)->name() == name) {
2231 return shared_ptr<Route> ((Route*) 0);
2235 Session::route_by_id (PBD::ID id)
2237 shared_ptr<RouteList> r = routes.reader ();
2239 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2240 if ((*i)->id() == id) {
2245 return shared_ptr<Route> ((Route*) 0);
2249 Session::route_by_remote_id (uint32_t id)
2251 shared_ptr<RouteList> r = routes.reader ();
2253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2254 if ((*i)->remote_control_id() == id) {
2259 return shared_ptr<Route> ((Route*) 0);
2263 Session::find_current_end ()
2265 if (_state_of_the_state & Loading) {
2269 jack_nframes_t max = get_maximum_extent ();
2271 if (max > end_location->end()) {
2272 end_location->set_end (max);
2274 DurationChanged(); /* EMIT SIGNAL */
2279 Session::get_maximum_extent () const
2281 jack_nframes_t max = 0;
2284 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2286 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2287 Playlist* pl = (*i)->playlist();
2288 if ((me = pl->get_maximum_extent()) > max) {
2296 boost::shared_ptr<Diskstream>
2297 Session::diskstream_by_name (string name)
2299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2302 if ((*i)->name() == name) {
2307 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2310 boost::shared_ptr<Diskstream>
2311 Session::diskstream_by_id (const PBD::ID& id)
2313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2315 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2316 if ((*i)->id() == id) {
2321 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2324 /* AudioRegion management */
2327 Session::new_region_name (string old)
2329 string::size_type last_period;
2331 string::size_type len = old.length() + 64;
2334 if ((last_period = old.find_last_of ('.')) == string::npos) {
2336 /* no period present - add one explicitly */
2339 last_period = old.length() - 1;
2344 number = atoi (old.substr (last_period+1).c_str());
2348 while (number < (UINT_MAX-1)) {
2350 AudioRegionList::const_iterator i;
2355 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2358 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2359 if (i->second->name() == sbuf) {
2364 if (i == audio_regions.end()) {
2369 if (number != (UINT_MAX-1)) {
2373 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2378 Session::region_name (string& result, string base, bool newlevel) const
2385 Glib::Mutex::Lock lm (region_lock);
2387 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2395 /* XXX this is going to be slow. optimize me later */
2400 string::size_type pos;
2402 pos = base.find_last_of ('.');
2404 /* pos may be npos, but then we just use entire base */
2406 subbase = base.substr (0, pos);
2410 bool name_taken = true;
2413 Glib::Mutex::Lock lm (region_lock);
2415 for (int n = 1; n < 5000; ++n) {
2418 snprintf (buf, sizeof (buf), ".%d", n);
2423 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2424 if (i->second->name() == result) {
2437 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2445 Session::add_region (Region* region)
2447 AudioRegion* ar = 0;
2448 AudioRegion* oar = 0;
2452 Glib::Mutex::Lock lm (region_lock);
2454 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2456 AudioRegionList::iterator x;
2458 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2460 oar = dynamic_cast<AudioRegion*> (x->second);
2462 if (ar->region_list_equivalent (*oar)) {
2467 if (x == audio_regions.end()) {
2469 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2471 entry.first = region->id();
2474 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2485 fatal << _("programming error: ")
2486 << X_("unknown region type passed to Session::add_region()")
2493 /* mark dirty because something has changed even if we didn't
2494 add the region to the region list.
2500 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2501 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2502 AudioRegionAdded (ar); /* EMIT SIGNAL */
2507 Session::region_changed (Change what_changed, Region* region)
2509 if (what_changed & Region::HiddenChanged) {
2510 /* relay hidden changes */
2511 RegionHiddenChange (region);
2516 Session::region_renamed (Region* region)
2518 add_region (region);
2522 Session::remove_region (Region* region)
2524 AudioRegionList::iterator i;
2525 AudioRegion* ar = 0;
2526 bool removed = false;
2529 Glib::Mutex::Lock lm (region_lock);
2531 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2532 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2533 audio_regions.erase (i);
2539 fatal << _("programming error: ")
2540 << X_("unknown region type passed to Session::remove_region()")
2546 /* mark dirty because something has changed even if we didn't
2547 remove the region from the region list.
2553 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2558 Session::find_whole_file_parent (AudioRegion& child)
2560 AudioRegionList::iterator i;
2561 AudioRegion* region;
2562 Glib::Mutex::Lock lm (region_lock);
2564 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2568 if (region->whole_file()) {
2570 if (child.source_equivalent (*region)) {
2580 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2582 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2583 (*i)->get_region_list_equivalent_regions (region, result);
2587 Session::destroy_region (Region* region)
2589 AudioRegion* aregion;
2591 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2595 if (aregion->playlist()) {
2596 aregion->playlist()->destroy_region (region);
2599 vector<Source*> srcs;
2601 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2602 srcs.push_back (&aregion->source (n));
2605 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2607 if ((*i)->use_cnt() == 0) {
2608 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2610 (afs)->mark_for_remove ();
2620 Session::destroy_regions (list<Region*> regions)
2622 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2623 destroy_region (*i);
2629 Session::remove_last_capture ()
2633 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2635 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2636 list<Region*>& l = (*i)->last_capture_regions();
2639 r.insert (r.end(), l.begin(), l.end());
2644 destroy_regions (r);
2649 Session::remove_region_from_region_list (Region& r)
2655 /* Source Management */
2658 Session::add_audio_source (AudioSource* source)
2660 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2663 Glib::Mutex::Lock lm (audio_source_lock);
2664 entry.first = source->id();
2665 entry.second = source;
2666 audio_sources.insert (entry);
2669 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2672 SourceAdded (source); /* EMIT SIGNAL */
2676 Session::remove_source (Source* source)
2678 AudioSourceList::iterator i;
2681 Glib::Mutex::Lock lm (audio_source_lock);
2683 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2684 audio_sources.erase (i);
2688 if (!_state_of_the_state & InCleanup) {
2690 /* save state so we don't end up with a session file
2691 referring to non-existent sources.
2694 save_state (_current_snapshot_name);
2697 SourceRemoved(source); /* EMIT SIGNAL */
2701 Session::source_by_id (const PBD::ID& id)
2703 Glib::Mutex::Lock lm (audio_source_lock);
2704 AudioSourceList::iterator i;
2707 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2711 /* XXX search MIDI or other searches here */
2717 Session::peak_path_from_audio_path (string audio_path)
2719 /* XXX hardly bombproof! fix me */
2723 res = Glib::path_get_dirname (audio_path);
2724 res = Glib::path_get_dirname (res);
2726 res += peak_dir_name;
2728 res += PBD::basename_nosuffix (audio_path);
2735 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2738 string old_basename = PBD::basename_nosuffix (oldname);
2739 string new_legalized = legalize_for_path (newname);
2741 /* note: we know (or assume) the old path is already valid */
2745 /* destructive file sources have a name of the form:
2747 /path/to/Tnnnn-NAME(%[LR])?.wav
2749 the task here is to replace NAME with the new name.
2752 /* find last slash */
2756 string::size_type slash;
2757 string::size_type dash;
2759 if ((slash = path.find_last_of ('/')) == string::npos) {
2763 dir = path.substr (0, slash+1);
2765 /* '-' is not a legal character for the NAME part of the path */
2767 if ((dash = path.find_last_of ('-')) == string::npos) {
2771 prefix = path.substr (slash+1, dash-(slash+1));
2776 path += new_legalized;
2777 path += ".wav"; /* XXX gag me with a spoon */
2781 /* non-destructive file sources have a name of the form:
2783 /path/to/NAME-nnnnn(%[LR])?.wav
2785 the task here is to replace NAME with the new name.
2790 string::size_type slash;
2791 string::size_type dash;
2792 string::size_type postfix;
2794 /* find last slash */
2796 if ((slash = path.find_last_of ('/')) == string::npos) {
2800 dir = path.substr (0, slash+1);
2802 /* '-' is not a legal character for the NAME part of the path */
2804 if ((dash = path.find_last_of ('-')) == string::npos) {
2808 suffix = path.substr (dash+1);
2810 // Suffix is now everything after the dash. Now we need to eliminate
2811 // the nnnnn part, which is done by either finding a '%' or a '.'
2813 postfix = suffix.find_last_of ("%");
2814 if (postfix == string::npos) {
2815 postfix = suffix.find_last_of ('.');
2818 if (postfix != string::npos) {
2819 suffix = suffix.substr (postfix);
2821 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2825 const uint32_t limit = 10000;
2826 char buf[PATH_MAX+1];
2828 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2830 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2832 if (access (buf, F_OK) != 0) {
2840 error << "FATAL ERROR! Could not find a " << endl;
2849 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2853 char buf[PATH_MAX+1];
2854 const uint32_t limit = 10000;
2858 legalized = legalize_for_path (name);
2860 /* find a "version" of the file name that doesn't exist in
2861 any of the possible directories.
2864 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2866 vector<space_and_path>::iterator i;
2867 uint32_t existing = 0;
2869 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2874 spath += tape_dir_name;
2876 spath += sound_dir_name;
2881 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2882 } else if (nchan == 2) {
2884 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2886 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2888 } else if (nchan < 26) {
2889 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2891 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2899 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2900 } else if (nchan == 2) {
2902 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2904 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2906 } else if (nchan < 26) {
2907 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2909 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2913 if (access (buf, F_OK) == 0) {
2918 if (existing == 0) {
2923 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2924 throw failed_constructor();
2928 /* we now have a unique name for the file, but figure out where to
2935 spath = tape_dir ();
2937 spath = discover_best_sound_dir ();
2940 string::size_type pos = foo.find_last_of ('/');
2942 if (pos == string::npos) {
2945 spath += foo.substr (pos + 1);
2952 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2954 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2956 /* this might throw failed_constructor(), which is OK */
2959 return new DestructiveFileSource (spath,
2960 Config->get_native_file_data_format(),
2961 Config->get_native_file_header_format(),
2964 return new SndFileSource (spath,
2965 Config->get_native_file_data_format(),
2966 Config->get_native_file_header_format(),
2971 /* Playlist management */
2974 Session::playlist_by_name (string name)
2976 Glib::Mutex::Lock lm (playlist_lock);
2977 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2978 if ((*i)->name() == name) {
2982 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2983 if ((*i)->name() == name) {
2991 Session::add_playlist (Playlist* playlist)
2993 if (playlist->hidden()) {
2998 Glib::Mutex::Lock lm (playlist_lock);
2999 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3000 playlists.insert (playlists.begin(), playlist);
3002 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3003 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3009 PlaylistAdded (playlist); /* EMIT SIGNAL */
3013 Session::track_playlist (Playlist* pl, bool inuse)
3015 PlaylistList::iterator x;
3018 Glib::Mutex::Lock lm (playlist_lock);
3021 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3023 unused_playlists.insert (pl);
3025 if ((x = playlists.find (pl)) != playlists.end()) {
3026 playlists.erase (x);
3031 //cerr << "shifting playlist to used: " << pl->name() << endl;
3033 playlists.insert (pl);
3035 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3036 unused_playlists.erase (x);
3043 Session::remove_playlist (Playlist* playlist)
3045 if (_state_of_the_state & Deletion) {
3050 Glib::Mutex::Lock lm (playlist_lock);
3051 // cerr << "removing playlist: " << playlist->name() << endl;
3053 PlaylistList::iterator i;
3055 i = find (playlists.begin(), playlists.end(), playlist);
3057 if (i != playlists.end()) {
3058 playlists.erase (i);
3061 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3062 if (i != unused_playlists.end()) {
3063 unused_playlists.erase (i);
3070 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3074 Session::set_audition (AudioRegion* r)
3076 pending_audition_region = r;
3077 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3078 schedule_butler_transport_work ();
3082 Session::non_realtime_set_audition ()
3084 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3085 auditioner->audition_current_playlist ();
3086 } else if (pending_audition_region) {
3087 auditioner->audition_region (*pending_audition_region);
3089 pending_audition_region = 0;
3090 AuditionActive (true); /* EMIT SIGNAL */
3094 Session::audition_playlist ()
3096 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3097 ev->set_ptr ((void*) 0xfeedface);
3102 Session::audition_region (Region& r)
3104 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3106 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3113 Session::cancel_audition ()
3115 if (auditioner->active()) {
3116 auditioner->cancel_audition ();
3117 AuditionActive (false); /* EMIT SIGNAL */
3122 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3124 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3128 Session::remove_empty_sounds ()
3131 PathScanner scanner;
3136 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3138 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3140 if (AudioFileSource::is_empty (*(*i))) {
3142 unlink ((*i)->c_str());
3144 string peak_path = peak_path_from_audio_path (**i);
3145 unlink (peak_path.c_str());
3151 delete possible_audiofiles;
3155 Session::is_auditioning () const
3157 /* can be called before we have an auditioner object */
3159 return auditioner->active();
3166 Session::set_all_solo (bool yn)
3168 shared_ptr<RouteList> r = routes.reader ();
3170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3171 if (!(*i)->hidden()) {
3172 (*i)->set_solo (yn, this);
3180 Session::set_all_mute (bool yn)
3182 shared_ptr<RouteList> r = routes.reader ();
3184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3185 if (!(*i)->hidden()) {
3186 (*i)->set_mute (yn, this);
3194 Session::n_diskstreams () const
3198 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3200 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3201 if (!(*i)->hidden()) {
3209 Session::graph_reordered ()
3211 /* don't do this stuff if we are setting up connections
3212 from a set_state() call.
3215 if (_state_of_the_state & InitialConnecting) {
3221 /* force all diskstreams to update their capture offset values to
3222 reflect any changes in latencies within the graph.
3225 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3227 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3228 (*i)->set_capture_offset ();
3233 Session::record_disenable_all ()
3235 record_enable_change_all (false);
3239 Session::record_enable_all ()
3241 record_enable_change_all (true);
3245 Session::record_enable_change_all (bool yn)
3247 shared_ptr<RouteList> r = routes.reader ();
3249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3252 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3253 at->set_record_enable (yn, this);
3257 /* since we don't keep rec-enable state, don't mark session dirty */
3261 Session::add_redirect (Redirect* redirect)
3265 PortInsert* port_insert;
3266 PluginInsert* plugin_insert;
3268 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3269 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3270 _port_inserts.insert (_port_inserts.begin(), port_insert);
3271 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3272 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3274 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3277 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3278 _sends.insert (_sends.begin(), send);
3280 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3284 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3290 Session::remove_redirect (Redirect* redirect)
3294 PortInsert* port_insert;
3295 PluginInsert* plugin_insert;
3297 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3298 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3299 _port_inserts.remove (port_insert);
3300 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3301 _plugin_inserts.remove (plugin_insert);
3303 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3306 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3307 _sends.remove (send);
3309 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3317 Session::available_capture_duration ()
3319 const double scale = 4096.0 / sizeof (Sample);
3321 if (_total_free_4k_blocks * scale > (double) max_frames) {
3325 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3329 Session::add_connection (ARDOUR::Connection* connection)
3332 Glib::Mutex::Lock guard (connection_lock);
3333 _connections.push_back (connection);
3336 ConnectionAdded (connection); /* EMIT SIGNAL */
3342 Session::remove_connection (ARDOUR::Connection* connection)
3344 bool removed = false;
3347 Glib::Mutex::Lock guard (connection_lock);
3348 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3350 if (i != _connections.end()) {
3351 _connections.erase (i);
3357 ConnectionRemoved (connection); /* EMIT SIGNAL */
3363 ARDOUR::Connection *
3364 Session::connection_by_name (string name) const
3366 Glib::Mutex::Lock lm (connection_lock);
3368 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3369 if ((*i)->name() == name) {
3378 Session::set_edit_mode (EditMode mode)
3383 Glib::Mutex::Lock lm (playlist_lock);
3385 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3386 (*i)->set_edit_mode (mode);
3391 ControlChanged (EditingMode); /* EMIT SIGNAL */
3395 Session::tempo_map_changed (Change ignored)
3402 Session::ensure_passthru_buffers (uint32_t howmany)
3404 while (howmany > _passthru_buffers.size()) {
3406 #ifdef NO_POSIX_MEMALIGN
3407 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3409 posix_memalign((void **)&p,16,current_block_size * 4);
3411 _passthru_buffers.push_back (p);
3415 #ifdef NO_POSIX_MEMALIGN
3416 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3418 posix_memalign((void **)&p,16,current_block_size * 4);
3420 memset (p, 0, sizeof (Sample) * current_block_size);
3421 _silent_buffers.push_back (p);
3425 #ifdef NO_POSIX_MEMALIGN
3426 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3428 posix_memalign((void **)&p,16,current_block_size * 4);
3430 memset (p, 0, sizeof (Sample) * current_block_size);
3431 _send_buffers.push_back (p);
3434 allocate_pan_automation_buffers (current_block_size, howmany, false);
3438 Session::next_send_name ()
3441 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3446 Session::next_insert_name ()
3449 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3453 /* Named Selection management */
3456 Session::named_selection_by_name (string name)
3458 Glib::Mutex::Lock lm (named_selection_lock);
3459 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3460 if ((*i)->name == name) {
3468 Session::add_named_selection (NamedSelection* named_selection)
3471 Glib::Mutex::Lock lm (named_selection_lock);
3472 named_selections.insert (named_selections.begin(), named_selection);
3477 NamedSelectionAdded (); /* EMIT SIGNAL */
3481 Session::remove_named_selection (NamedSelection* named_selection)
3483 bool removed = false;
3486 Glib::Mutex::Lock lm (named_selection_lock);
3488 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3490 if (i != named_selections.end()) {
3492 named_selections.erase (i);
3499 NamedSelectionRemoved (); /* EMIT SIGNAL */
3504 Session::reset_native_file_format ()
3506 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3508 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3509 (*i)->reset_write_sources (false);
3514 Session::route_name_unique (string n) const
3516 shared_ptr<RouteList> r = routes.reader ();
3518 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3519 if ((*i)->name() == n) {
3528 Session::cleanup_audio_file_source (AudioFileSource& fs)
3530 return fs.move_to_trash (dead_sound_dir_name);
3534 Session::n_playlists () const
3536 Glib::Mutex::Lock lm (playlist_lock);
3537 return playlists.size();
3541 Session::set_solo_model (SoloModel sm)
3543 if (sm != _solo_model) {
3545 ControlChanged (SoloingModel);
3551 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3553 if (!force && howmany <= _npan_buffers) {
3557 if (_pan_automation_buffer) {
3559 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3560 delete [] _pan_automation_buffer[i];
3563 delete [] _pan_automation_buffer;
3566 _pan_automation_buffer = new pan_t*[howmany];
3568 for (uint32_t i = 0; i < howmany; ++i) {
3569 _pan_automation_buffer[i] = new pan_t[nframes];
3572 _npan_buffers = howmany;
3576 Session::freeze (InterThreadInfo& itt)
3578 shared_ptr<RouteList> r = routes.reader ();
3580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3584 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3585 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3596 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3597 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3601 AudioFileSource* fsource;
3603 char buf[PATH_MAX+1];
3606 jack_nframes_t position;
3607 jack_nframes_t this_chunk;
3608 jack_nframes_t to_do;
3609 vector<Sample*> buffers;
3611 // any bigger than this seems to cause stack overflows in called functions
3612 const jack_nframes_t chunk_size = (128 * 1024)/4;
3614 g_atomic_int_set (&processing_prohibited, 1);
3616 /* call tree *MUST* hold route_lock */
3618 if ((playlist = track.diskstream()->playlist()) == 0) {
3622 /* external redirects will be a problem */
3624 if (track.has_external_redirects()) {
3628 nchans = track.audio_diskstream()->n_channels();
3630 dir = discover_best_sound_dir ();
3632 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3634 for (x = 0; x < 99999; ++x) {
3635 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3636 if (access (buf, F_OK) != 0) {
3642 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3647 fsource = new SndFileSource (buf,
3648 Config->get_native_file_data_format(),
3649 Config->get_native_file_header_format(),
3654 catch (failed_constructor& err) {
3655 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3659 srcs.push_back(fsource);
3662 /* XXX need to flush all redirects */
3667 /* create a set of reasonably-sized buffers */
3669 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3671 #ifdef NO_POSIX_MEMALIGN
3672 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3674 posix_memalign((void **)&b,16,chunk_size * 4);
3676 buffers.push_back (b);
3679 while (to_do && !itt.cancel) {
3681 this_chunk = min (to_do, chunk_size);
3683 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3688 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3689 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3692 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3698 start += this_chunk;
3699 to_do -= this_chunk;
3701 itt.progress = (float) (1.0 - ((double) to_do / len));
3710 xnow = localtime (&now);
3712 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3713 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3715 afs->update_header (position, *xnow, now);
3719 /* build peakfile for new source */
3721 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3722 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3724 afs->build_peaks ();
3733 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3734 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3736 afs->mark_for_remove ();
3742 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3746 g_atomic_int_set (&processing_prohibited, 0);
3754 Session::get_silent_buffers (uint32_t howmany)
3756 for (uint32_t i = 0; i < howmany; ++i) {
3757 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3759 return _silent_buffers;
3763 Session::ntracks () const
3766 shared_ptr<RouteList> r = routes.reader ();
3768 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3769 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3778 Session::nbusses () const
3781 shared_ptr<RouteList> r = routes.reader ();
3783 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3784 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3793 Session::set_layer_model (LayerModel lm)
3795 if (lm != layer_model) {
3798 ControlChanged (LayeringModel);
3803 Session::set_xfade_model (CrossfadeModel xm)
3805 if (xm != xfade_model) {
3808 ControlChanged (CrossfadingModel);
3813 Session::add_curve(Curve *curve)
3815 curves[curve->id()] = curve;
3819 Session::add_automation_list(AutomationList *al)
3821 automation_lists[al->id()] = al;