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::peak_dir_name = X_("peaks");
80 const char* Session::dead_sound_dir_name = X_("dead_sounds");
82 Session::compute_peak_t Session::compute_peak = 0;
83 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
84 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
85 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
87 sigc::signal<int> Session::AskAboutPendingState;
90 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
97 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
98 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
104 /* check to see if it exists, and what it is */
106 if (stat (str.c_str(), &statbuf)) {
107 if (errno == ENOENT) {
110 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
118 /* it exists, so it must either be the name
119 of the directory, or the name of the statefile
123 if (S_ISDIR (statbuf.st_mode)) {
125 string::size_type slash = str.find_last_of ('/');
127 if (slash == string::npos) {
129 /* a subdirectory of cwd, so statefile should be ... */
135 tmp += _statefile_suffix;
139 if (stat (tmp.c_str(), &statbuf)) {
140 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
150 /* some directory someplace in the filesystem.
151 the snapshot name is the directory name
156 snapshot = str.substr (slash+1);
160 } else if (S_ISREG (statbuf.st_mode)) {
162 string::size_type slash = str.find_last_of ('/');
163 string::size_type suffix;
165 /* remove the suffix */
167 if (slash != string::npos) {
168 snapshot = str.substr (slash+1);
173 suffix = snapshot.find (_statefile_suffix);
175 if (suffix == string::npos) {
176 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
182 snapshot = snapshot.substr (0, suffix);
184 if (slash == string::npos) {
186 /* we must be in the directory where the
187 statefile lives. get it using cwd().
190 char cwd[PATH_MAX+1];
192 if (getcwd (cwd, sizeof (cwd)) == 0) {
193 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
202 /* full path to the statefile */
204 path = str.substr (0, slash);
209 /* what type of file is it? */
210 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
216 /* its the name of a new directory. get the name
220 string::size_type slash = str.find_last_of ('/');
222 if (slash == string::npos) {
224 /* no slash, just use the name, but clean it up */
226 path = legalize_for_path (str);
232 snapshot = str.substr (slash+1);
239 Session::Session (AudioEngine &eng,
241 string snapshot_name,
242 string* mix_template)
245 _mmc_port (default_mmc_port),
246 _mtc_port (default_mtc_port),
247 _midi_port (default_midi_port),
248 pending_events (2048),
249 midi_requests (128), // the size of this should match the midi request pool size
254 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
256 n_physical_outputs = _engine.n_physical_outputs();
257 n_physical_inputs = _engine.n_physical_inputs();
259 first_stage_init (fullpath, snapshot_name);
261 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
262 throw failed_constructor ();
265 if (second_stage_init (new_session)) {
266 throw failed_constructor ();
269 store_recent_sessions(_name, _path);
271 bool was_dirty = dirty();
273 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
276 DirtyChanged (); /* EMIT SIGNAL */
280 Session::Session (AudioEngine &eng,
282 string snapshot_name,
283 AutoConnectOption input_ac,
284 AutoConnectOption output_ac,
285 uint32_t control_out_channels,
286 uint32_t master_out_channels,
287 uint32_t requested_physical_in,
288 uint32_t requested_physical_out,
289 jack_nframes_t initial_length)
292 _mmc_port (default_mmc_port),
293 _mtc_port (default_mtc_port),
294 _midi_port (default_midi_port),
295 pending_events (2048),
302 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
304 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
305 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
307 first_stage_init (fullpath, snapshot_name);
309 if (create (new_session, 0, initial_length)) {
310 throw failed_constructor ();
313 if (control_out_channels) {
315 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
320 if (master_out_channels) {
322 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
326 /* prohibit auto-connect to master, because there isn't one */
327 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
330 input_auto_connect = input_ac;
331 output_auto_connect = output_ac;
333 if (second_stage_init (new_session)) {
334 throw failed_constructor ();
337 store_recent_sessions(_name, _path);
339 bool was_dirty = dirty ();
341 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
344 DirtyChanged (); /* EMIT SIGNAL */
350 /* if we got to here, leaving pending capture state around
354 remove_pending_capture_state ();
356 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
357 _engine.remove_session ();
359 going_away (); /* EMIT SIGNAL */
361 terminate_butler_thread ();
362 terminate_midi_thread ();
363 terminate_feedback ();
365 if (click_data && click_data != default_click) {
366 delete [] click_data;
369 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
370 delete [] click_emphasis_data;
384 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
388 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
392 #undef TRACK_DESTRUCTION
393 #ifdef TRACK_DESTRUCTION
394 cerr << "delete named selections\n";
395 #endif /* TRACK_DESTRUCTION */
396 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
397 NamedSelectionList::iterator tmp;
406 #ifdef TRACK_DESTRUCTION
407 cerr << "delete playlists\n";
408 #endif /* TRACK_DESTRUCTION */
409 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
410 PlaylistList::iterator tmp;
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete audio regions\n";
422 #endif /* TRACK_DESTRUCTION */
423 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
424 AudioRegionList::iterator tmp;
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete routes\n";
436 #endif /* TRACK_DESTRUCTION */
437 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
438 RouteList::iterator tmp;
445 #ifdef TRACK_DESTRUCTION
446 cerr << "delete diskstreams\n";
447 #endif /* TRACK_DESTRUCTION */
448 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
449 DiskStreamList::iterator tmp;
459 #ifdef TRACK_DESTRUCTION
460 cerr << "delete sources\n";
461 #endif /* TRACK_DESTRUCTION */
462 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
463 SourceList::iterator tmp;
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete mix groups\n";
475 #endif /* TRACK_DESTRUCTION */
476 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
477 list<RouteGroup*>::iterator tmp;
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete edit groups\n";
489 #endif /* TRACK_DESTRUCTION */
490 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
491 list<RouteGroup*>::iterator tmp;
501 #ifdef TRACK_DESTRUCTION
502 cerr << "delete connections\n";
503 #endif /* TRACK_DESTRUCTION */
504 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
505 ConnectionList::iterator tmp;
515 if (butler_mixdown_buffer) {
516 delete [] butler_mixdown_buffer;
519 if (butler_gain_buffer) {
520 delete [] butler_gain_buffer;
523 Crossfade::set_buffer_size (0);
535 Session::set_worst_io_latencies (bool take_lock)
537 _worst_output_latency = 0;
538 _worst_input_latency = 0;
540 if (!_engine.connected()) {
545 route_lock.read_lock ();
548 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
549 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
550 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
554 route_lock.unlock ();
559 Session::when_engine_running ()
561 string first_physical_output;
563 /* we don't want to run execute this again */
565 first_time_running.disconnect ();
567 set_block_size (_engine.frames_per_cycle());
568 set_frame_rate (_engine.frame_rate());
570 /* every time we reconnect, recompute worst case output latencies */
572 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
574 if (synced_to_jack()) {
575 _engine.transport_stop ();
578 if (Config->get_jack_time_master()) {
579 _engine.transport_locate (_transport_frame);
587 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
589 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
591 /* existing state for Click */
593 if (_click_io->set_state (*child->children().front()) == 0) {
595 _clicking = click_requested;
599 error << _("could not setup Click I/O") << endmsg;
605 /* default state for Click */
607 first_physical_output = _engine.get_nth_physical_output (0);
609 if (first_physical_output.length()) {
610 if (_click_io->add_output_port (first_physical_output, this)) {
611 // relax, even though its an error
613 _clicking = click_requested;
619 catch (failed_constructor& err) {
620 error << _("cannot setup Click I/O") << endmsg;
623 set_worst_io_latencies (true);
626 ControlChanged (Clicking); /* EMIT SIGNAL */
629 if (auditioner == 0) {
631 /* we delay creating the auditioner till now because
632 it makes its own connections to ports named
633 in the ARDOUR_RC config file. the engine has
634 to be running for this to work.
638 auditioner = new Auditioner (*this);
641 catch (failed_constructor& err) {
642 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
646 /* Create a set of Connection objects that map
647 to the physical outputs currently available
652 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
654 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
656 Connection* c = new OutputConnection (buf, true);
659 c->add_connection (0, _engine.get_nth_physical_output (np));
664 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
666 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
668 Connection* c = new InputConnection (buf, true);
671 c->add_connection (0, _engine.get_nth_physical_input (np));
678 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
680 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
682 Connection* c = new OutputConnection (buf, true);
686 c->add_connection (0, _engine.get_nth_physical_output (np));
687 c->add_connection (1, _engine.get_nth_physical_output (np+1));
692 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
694 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
696 Connection* c = new InputConnection (buf, true);
700 c->add_connection (0, _engine.get_nth_physical_input (np));
701 c->add_connection (1, _engine.get_nth_physical_input (np+1));
710 /* create master/control ports */
715 /* force the master to ignore any later call to this */
717 if (_master_out->pending_state_node) {
718 _master_out->ports_became_legal();
721 /* no panner resets till we are through */
723 _master_out->defer_pan_reset ();
725 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
726 if (_master_out->add_input_port ("", this)) {
727 error << _("cannot setup master inputs")
733 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
734 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
735 error << _("cannot setup master outputs")
742 _master_out->allow_pan_reset ();
746 Connection* c = new OutputConnection (_("Master Out"), true);
748 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
750 c->add_connection ((int) n, _master_out->input(n)->name());
757 /* catch up on send+insert cnts */
761 for (slist<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
764 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
765 if (id > insert_cnt) {
773 for (slist<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
776 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
783 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
785 /* hook us up to the engine */
787 _engine.set_session (this);
789 _state_of_the_state = Clean;
791 DirtyChanged (); /* EMIT SIGNAL */
795 Session::hookup_io ()
797 /* stop graph reordering notifications from
798 causing resorts, etc.
801 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
803 /* Tell all IO objects to create their ports */
810 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
811 if (_control_out->add_input_port ("", this)) {
812 error << _("cannot setup control inputs")
818 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
819 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
820 error << _("cannot set up master outputs")
828 /* Tell all IO objects to connect themselves together */
830 IO::enable_connecting ();
832 /* Now reset all panners */
834 IO::reset_panners ();
836 /* Anyone who cares about input state, wake up and do something */
838 IOConnectionsComplete (); /* EMIT SIGNAL */
840 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
842 /* now handle the whole enchilada as if it was one
848 /* update mixer solo state */
854 Session::playlist_length_changed (Playlist* pl)
856 /* we can't just increase end_location->end() if pl->get_maximum_extent()
857 if larger. if the playlist used to be the longest playlist,
858 and its now shorter, we have to decrease end_location->end(). hence,
859 we have to iterate over all diskstreams and check the
860 playlists currently in use.
866 Session::diskstream_playlist_changed (DiskStream* dstream)
870 if ((playlist = dstream->playlist()) != 0) {
871 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
874 /* see comment in playlist_length_changed () */
879 Session::record_enabling_legal () const
881 /* this used to be in here, but survey says.... we don't need to restrict it */
882 // if (record_status() == Recording) {
893 Session::set_auto_play (bool yn)
895 if (auto_play != yn) {
898 ControlChanged (AutoPlay);
903 Session::set_auto_return (bool yn)
905 if (auto_return != yn) {
908 ControlChanged (AutoReturn);
913 Session::set_crossfades_active (bool yn)
915 if (crossfades_active != yn) {
916 crossfades_active = yn;
918 ControlChanged (CrossFadesActive);
923 Session::set_do_not_record_plugins (bool yn)
925 if (do_not_record_plugins != yn) {
926 do_not_record_plugins = yn;
928 ControlChanged (RecordingPlugins);
933 Session::set_auto_input (bool yn)
935 if (auto_input != yn) {
938 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
939 /* auto-input only makes a difference if we're rolling */
941 /* Even though this can called from RT context we are using
942 a non-tentative rwlock here, because the action must occur.
943 The rarity and short potential lock duration makes this "OK"
945 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
946 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
947 if ((*i)->record_enabled ()) {
948 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
949 (*i)->monitor_input (!auto_input);
955 ControlChanged (AutoInput);
960 Session::reset_input_monitor_state ()
962 if (transport_rolling()) {
963 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
964 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
965 if ((*i)->record_enabled ()) {
966 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
967 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
971 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
972 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
973 if ((*i)->record_enabled ()) {
974 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
975 (*i)->monitor_input (Config->get_use_hardware_monitoring());
983 Session::set_input_auto_connect (bool yn)
986 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
988 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
994 Session::get_input_auto_connect () const
996 return (input_auto_connect & AutoConnectPhysical);
1000 Session::set_output_auto_connect (AutoConnectOption aco)
1002 output_auto_connect = aco;
1007 Session::auto_punch_start_changed (Location* location)
1009 replace_event (Event::PunchIn, location->start());
1011 if (get_record_enabled() && get_punch_in()) {
1012 /* capture start has been changed, so save new pending state */
1013 save_state ("", true);
1018 Session::auto_punch_end_changed (Location* location)
1020 jack_nframes_t when_to_stop = location->end();
1021 // when_to_stop += _worst_output_latency + _worst_input_latency;
1022 replace_event (Event::PunchOut, when_to_stop);
1026 Session::auto_punch_changed (Location* location)
1028 jack_nframes_t when_to_stop = location->end();
1030 replace_event (Event::PunchIn, location->start());
1031 //when_to_stop += _worst_output_latency + _worst_input_latency;
1032 replace_event (Event::PunchOut, when_to_stop);
1036 Session::auto_loop_changed (Location* location)
1038 replace_event (Event::AutoLoop, location->end(), location->start());
1040 if (transport_rolling() && get_auto_loop()) {
1042 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1044 if (_transport_frame > location->end()) {
1045 // relocate to beginning of loop
1046 clear_events (Event::LocateRoll);
1048 request_locate (location->start(), true);
1051 else if (seamless_loop && !loop_changing) {
1053 // schedule a locate-roll to refill the diskstreams at the
1054 // previous loop end
1055 loop_changing = true;
1057 if (location->end() > last_loopend) {
1058 clear_events (Event::LocateRoll);
1059 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1066 last_loopend = location->end();
1071 Session::set_auto_punch_location (Location* location)
1075 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1076 auto_punch_start_changed_connection.disconnect();
1077 auto_punch_end_changed_connection.disconnect();
1078 auto_punch_changed_connection.disconnect();
1079 existing->set_auto_punch (false, this);
1080 remove_event (existing->start(), Event::PunchIn);
1081 clear_events (Event::PunchOut);
1082 auto_punch_location_changed (0);
1087 if (location == 0) {
1091 if (location->end() <= location->start()) {
1092 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1096 auto_punch_start_changed_connection.disconnect();
1097 auto_punch_end_changed_connection.disconnect();
1098 auto_punch_changed_connection.disconnect();
1100 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1101 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1102 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1104 location->set_auto_punch (true, this);
1105 auto_punch_location_changed (location);
1109 Session::set_punch_in (bool yn)
1111 if (punch_in == yn) {
1117 if ((location = _locations.auto_punch_location()) != 0) {
1118 if ((punch_in = yn) == true) {
1119 replace_event (Event::PunchIn, location->start());
1121 remove_event (location->start(), Event::PunchIn);
1126 ControlChanged (PunchIn); /* EMIT SIGNAL */
1130 Session::set_punch_out (bool yn)
1132 if (punch_out == yn) {
1138 if ((location = _locations.auto_punch_location()) != 0) {
1139 if ((punch_out = yn) == true) {
1140 replace_event (Event::PunchOut, location->end());
1142 clear_events (Event::PunchOut);
1147 ControlChanged (PunchOut); /* EMIT SIGNAL */
1151 Session::set_auto_loop_location (Location* location)
1155 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1156 auto_loop_start_changed_connection.disconnect();
1157 auto_loop_end_changed_connection.disconnect();
1158 auto_loop_changed_connection.disconnect();
1159 existing->set_auto_loop (false, this);
1160 remove_event (existing->end(), Event::AutoLoop);
1161 auto_loop_location_changed (0);
1166 if (location == 0) {
1170 if (location->end() <= location->start()) {
1171 error << _("Session: you can't use a mark for auto loop") << endmsg;
1175 last_loopend = location->end();
1177 auto_loop_start_changed_connection.disconnect();
1178 auto_loop_end_changed_connection.disconnect();
1179 auto_loop_changed_connection.disconnect();
1181 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1183 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1185 location->set_auto_loop (true, this);
1186 auto_loop_location_changed (location);
1190 Session::locations_added (Location* ignored)
1196 Session::locations_changed ()
1198 _locations.apply (*this, &Session::handle_locations_changed);
1202 Session::handle_locations_changed (Locations::LocationList& locations)
1204 Locations::LocationList::iterator i;
1206 bool set_loop = false;
1207 bool set_punch = false;
1209 for (i = locations.begin(); i != locations.end(); ++i) {
1213 if (location->is_auto_punch()) {
1214 set_auto_punch_location (location);
1217 if (location->is_auto_loop()) {
1218 set_auto_loop_location (location);
1225 set_auto_loop_location (0);
1228 set_auto_punch_location (0);
1235 Session::enable_record ()
1237 /* XXX really atomic compare+swap here */
1238 if (atomic_read (&_record_status) != Recording) {
1239 atomic_set (&_record_status, Recording);
1240 _last_record_location = _transport_frame;
1241 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1243 if (Config->get_use_hardware_monitoring() && auto_input) {
1244 /* Even though this can be called from RT context we are using
1245 a non-tentative rwlock here, because the action must occur.
1246 The rarity and short potential lock duration makes this "OK"
1248 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1250 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1251 if ((*i)->record_enabled ()) {
1252 (*i)->monitor_input (true);
1257 RecordStateChanged ();
1262 Session::disable_record (bool force)
1266 if ((rs = (RecordState) atomic_read (&_record_status)) != Disabled) {
1268 if (!Config->get_latched_record_enable () || force) {
1269 atomic_set (&_record_status, Disabled);
1271 if (rs == Recording) {
1272 atomic_set (&_record_status, Enabled);
1276 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1278 if (Config->get_use_hardware_monitoring() && auto_input) {
1279 /* Even though this can be called from RT context we are using
1280 a non-tentative rwlock here, because the action must occur.
1281 The rarity and short potential lock duration makes this "OK"
1283 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1285 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1286 if ((*i)->record_enabled ()) {
1287 (*i)->monitor_input (false);
1292 RecordStateChanged (); /* emit signal */
1293 remove_pending_capture_state ();
1298 Session::step_back_from_record ()
1300 atomic_set (&_record_status, Enabled);
1302 if (Config->get_use_hardware_monitoring()) {
1303 /* Even though this can be called from RT context we are using
1304 a non-tentative rwlock here, because the action must occur.
1305 The rarity and short potential lock duration makes this "OK"
1307 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1309 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1310 if (auto_input && (*i)->record_enabled ()) {
1311 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1312 (*i)->monitor_input (false);
1319 Session::maybe_enable_record ()
1321 atomic_set (&_record_status, Enabled);
1323 /* XXX this save should really happen in another thread. its needed so that
1324 pending capture state can be recovered if we crash.
1327 save_state ("", true);
1329 if (_transport_speed) {
1334 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1335 RecordStateChanged (); /* EMIT SIGNAL */
1342 Session::audible_frame () const
1345 jack_nframes_t offset;
1348 /* the first of these two possible settings for "offset"
1349 mean that the audible frame is stationary until
1350 audio emerges from the latency compensation
1353 the second means that the audible frame is stationary
1354 until audio would emerge from a physical port
1355 in the absence of any plugin latency compensation
1358 offset = _worst_output_latency;
1360 if (offset > current_block_size) {
1361 offset -= current_block_size;
1363 /* XXX is this correct? if we have no external
1364 physical connections and everything is internal
1365 then surely this is zero? still, how
1366 likely is that anyway?
1368 offset = current_block_size;
1371 if (synced_to_jack()) {
1372 tf = _engine.transport_frame();
1374 tf = _transport_frame;
1377 if (_transport_speed == 0) {
1387 if (!non_realtime_work_pending()) {
1391 /* take latency into account */
1400 Session::set_frame_rate (jack_nframes_t frames_per_second)
1402 /** \fn void Session::set_frame_size(jack_nframes_t)
1403 the AudioEngine object that calls this guarantees
1404 that it will not be called while we are also in
1405 ::process(). Its fine to do things that block
1409 _current_frame_rate = frames_per_second;
1410 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1412 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1416 /* XXX need to reset/reinstantiate all LADSPA plugins */
1420 Session::set_block_size (jack_nframes_t nframes)
1422 /* the AudioEngine guarantees
1423 that it will not be called while we are also in
1424 ::process(). It is therefore fine to do things that block
1429 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1430 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1431 vector<Sample*>::iterator i;
1434 current_block_size = nframes;
1436 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1440 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1444 _passthru_buffers.clear ();
1445 _silent_buffers.clear ();
1447 ensure_passthru_buffers (np);
1449 if (_gain_automation_buffer) {
1450 delete [] _gain_automation_buffer;
1452 _gain_automation_buffer = new gain_t[nframes];
1454 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1456 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1457 (*i)->set_block_size (nframes);
1460 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1461 (*i)->set_block_size (nframes);
1464 set_worst_io_latencies (false);
1469 Session::set_default_fade (float steepness, float fade_msecs)
1472 jack_nframes_t fade_frames;
1474 /* Don't allow fade of less 1 frame */
1476 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1483 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1487 default_fade_msecs = fade_msecs;
1488 default_fade_steepness = steepness;
1491 // jlc, WTF is this!
1492 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1493 AudioRegion::set_default_fade (steepness, fade_frames);
1498 /* XXX have to do this at some point */
1499 /* foreach region using default fade, reset, then
1500 refill_all_diskstream_buffers ();
1505 struct RouteSorter {
1506 bool operator() (Route* r1, Route* r2) {
1507 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1509 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1512 if (r1->fed_by.empty()) {
1513 if (r2->fed_by.empty()) {
1514 /* no ardour-based connections inbound to either route. just use signal order */
1515 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1517 /* r2 has connections, r1 does not; run r1 early */
1521 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1528 trace_terminal (Route* r1, Route* rbase)
1532 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1533 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1537 /* make a copy of the existing list of routes that feed r1 */
1539 set<Route *> existing = r1->fed_by;
1541 /* for each route that feeds r1, recurse, marking it as feeding
1545 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1548 /* r2 is a route that feeds r1 which somehow feeds base. mark
1549 base as being fed by r2
1552 rbase->fed_by.insert (r2);
1556 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1560 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1564 /* now recurse, so that we can mark base as being fed by
1565 all routes that feed r2
1568 trace_terminal (r2, rbase);
1575 Session::resort_routes (void* src)
1577 /* don't do anything here with signals emitted
1578 by Routes while we are being destroyed.
1581 if (_state_of_the_state & Deletion) {
1585 /* Caller MUST hold the route_lock */
1587 RouteList::iterator i, j;
1589 for (i = routes.begin(); i != routes.end(); ++i) {
1591 (*i)->fed_by.clear ();
1593 for (j = routes.begin(); j != routes.end(); ++j) {
1595 /* although routes can feed themselves, it will
1596 cause an endless recursive descent if we
1597 detect it. so don't bother checking for
1605 if ((*j)->feeds (*i)) {
1606 (*i)->fed_by.insert (*j);
1611 for (i = routes.begin(); i != routes.end(); ++i) {
1612 trace_terminal (*i, *i);
1619 cerr << "finished route resort\n";
1621 for (i = routes.begin(); i != routes.end(); ++i) {
1622 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1630 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1633 char track_name[32];
1635 uint32_t channels_used = 0;
1637 uint32_t nphysical_in;
1638 uint32_t nphysical_out;
1640 /* count existing audio tracks */
1643 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1644 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1645 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1646 if (!(*i)->hidden()) {
1648 channels_used += (*i)->n_inputs();
1654 /* check for duplicate route names, since we might have pre-existing
1655 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1656 save, close,restart,add new route - first named route is now
1661 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1662 if (route_by_name (track_name) == 0) {
1667 } while (n < (UINT_MAX-1));
1669 if (input_auto_connect & AutoConnectPhysical) {
1670 nphysical_in = n_physical_inputs;
1675 if (output_auto_connect & AutoConnectPhysical) {
1676 nphysical_out = n_physical_outputs;
1682 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1684 if (track->ensure_io (input_channels, output_channels, false, this)) {
1685 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1686 input_channels, output_channels)
1691 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1695 if (input_auto_connect & AutoConnectPhysical) {
1696 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1699 if (port.length() && track->connect_input (track->input (x), port, this)) {
1705 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1709 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1710 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1711 } else if (output_auto_connect & AutoConnectMaster) {
1713 port = _master_out->input (x%_master_out->n_inputs())->name();
1717 if (port.length() && track->connect_output (track->output (x), port, this)) {
1723 vector<string> cports;
1724 uint32_t ni = _control_out->n_inputs();
1726 for (n = 0; n < ni; ++n) {
1727 cports.push_back (_control_out->input(n)->name());
1730 track->set_control_outs (cports);
1733 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1737 track->set_remote_control_id (ntracks());
1740 catch (failed_constructor &err) {
1741 error << _("Session: could not create new audio track.") << endmsg;
1749 Session::new_audio_route (int input_channels, int output_channels)
1756 /* count existing audio busses */
1759 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1760 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1761 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1762 if (!(*i)->hidden()) {
1770 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1771 if (route_by_name (bus_name) == 0) {
1776 } while (n < (UINT_MAX-1));
1779 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1781 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1787 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1791 if (input_auto_connect & AutoConnectPhysical) {
1792 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1795 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1800 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1804 if (output_auto_connect & AutoConnectPhysical) {
1805 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1806 } else if (output_auto_connect & AutoConnectMaster) {
1808 port = _master_out->input (x%_master_out->n_inputs())->name();
1812 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1818 vector<string> cports;
1819 uint32_t ni = _control_out->n_inputs();
1821 for (uint32_t n = 0; n < ni; ++n) {
1822 cports.push_back (_control_out->input(n)->name());
1824 bus->set_control_outs (cports);
1830 catch (failed_constructor &err) {
1831 error << _("Session: could not create new route.") << endmsg;
1839 Session::add_route (Route* route)
1842 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1843 routes.push_front (route);
1847 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1848 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1849 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1850 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1852 if (route->master()) {
1853 _master_out = route;
1856 if (route->control()) {
1857 _control_out = route;
1861 save_state (_current_snapshot_name);
1863 RouteAdded (route); /* EMIT SIGNAL */
1867 Session::add_diskstream (DiskStream* dstream)
1869 /* need to do this in case we're rolling at the time, to prevent false underruns */
1870 dstream->do_refill(0, 0);
1873 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1874 diskstreams.push_back (dstream);
1877 /* take a reference to the diskstream, preventing it from
1878 ever being deleted until the session itself goes away,
1879 or chooses to remove it for its own purposes.
1883 dstream->set_block_size (current_block_size);
1885 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1886 /* this will connect to future changes, and check the current length */
1887 diskstream_playlist_changed (dstream);
1889 dstream->prepare ();
1892 save_state (_current_snapshot_name);
1894 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1898 Session::remove_route (Route& route)
1901 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1902 routes.remove (&route);
1904 /* deleting the master out seems like a dumb
1905 idea, but its more of a UI policy issue
1909 if (&route == _master_out) {
1913 if (&route == _control_out) {
1916 /* cancel control outs for all routes */
1918 vector<string> empty;
1920 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1921 (*r)->set_control_outs (empty);
1925 update_route_solo_state ();
1929 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1933 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1934 diskstreams.remove (&at->disk_stream());
1935 at->disk_stream().unref ();
1938 find_current_end ();
1941 update_latency_compensation (false, false);
1944 /* XXX should we disconnect from the Route's signals ? */
1946 save_state (_current_snapshot_name);
1952 Session::route_mute_changed (void* src)
1958 Session::route_solo_changed (void* src, Route* route)
1960 if (solo_update_disabled) {
1965 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1968 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1970 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1972 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1976 /* don't mess with busses */
1978 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1984 /* don't mess with tracks */
1986 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1991 if ((*i) != route &&
1992 ((*i)->mix_group () == 0 ||
1993 (*i)->mix_group () != route->mix_group () ||
1994 !route->mix_group ()->is_active())) {
1996 if ((*i)->soloed()) {
1998 /* if its already soloed, and solo latching is enabled,
1999 then leave it as it is.
2002 if (_solo_latched) {
2009 solo_update_disabled = true;
2010 (*i)->set_solo (false, src);
2011 solo_update_disabled = false;
2015 bool something_soloed = false;
2016 bool same_thing_soloed = false;
2017 bool signal = false;
2019 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2020 if ((*i)->soloed()) {
2021 something_soloed = true;
2022 if (dynamic_cast<AudioTrack*>(*i)) {
2024 same_thing_soloed = true;
2029 same_thing_soloed = true;
2037 if (something_soloed != currently_soloing) {
2039 currently_soloing = something_soloed;
2042 modify_solo_mute (is_track, same_thing_soloed);
2045 SoloActive (currently_soloing);
2052 Session::set_solo_latched (bool yn)
2054 if (yn != _solo_latched) {
2057 ControlChanged (SoloLatch);
2062 Session::update_route_solo_state ()
2065 bool is_track = false;
2066 bool signal = false;
2068 /* caller must hold RouteLock */
2070 /* this is where we actually implement solo by changing
2071 the solo mute setting of each track.
2074 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2075 if ((*i)->soloed()) {
2077 if (dynamic_cast<AudioTrack*>(*i)) {
2084 if (mute != currently_soloing) {
2086 currently_soloing = mute;
2089 if (!is_track && !mute) {
2091 /* nothing is soloed */
2093 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2094 (*i)->set_solo_mute (false);
2104 modify_solo_mute (is_track, mute);
2107 SoloActive (currently_soloing);
2112 Session::modify_solo_mute (bool is_track, bool mute)
2114 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2118 /* only alter track solo mute */
2120 if (dynamic_cast<AudioTrack*>(*i)) {
2121 if ((*i)->soloed()) {
2122 (*i)->set_solo_mute (!mute);
2124 (*i)->set_solo_mute (mute);
2130 /* only alter bus solo mute */
2132 if (!dynamic_cast<AudioTrack*>(*i)) {
2134 if ((*i)->soloed()) {
2136 (*i)->set_solo_mute (false);
2140 /* don't mute master or control outs
2141 in response to another bus solo
2144 if ((*i) != _master_out &&
2145 (*i) != _control_out) {
2146 (*i)->set_solo_mute (mute);
2157 Session::catch_up_on_solo ()
2159 /* this is called after set_state() to catch the full solo
2160 state, which can't be correctly determined on a per-route
2161 basis, but needs the global overview that only the session
2164 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2165 update_route_solo_state();
2169 Session::route_by_name (string name)
2171 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2173 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2174 if ((*i)->name() == name) {
2183 Session::find_current_end ()
2185 jack_nframes_t max = 0;
2188 if (_state_of_the_state & Loading) {
2192 /* Don't take the diskstream lock. Caller must have other ways to
2196 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2197 Playlist* pl = (*i)->playlist();
2198 if ((me = pl->get_maximum_extent()) > max) {
2203 if (max > end_location->end()) {
2204 end_location->set_end (max);
2206 DurationChanged(); /* EMIT SIGNAL */
2211 Session::diskstream_by_name (string name)
2213 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2215 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2216 if ((*i)->name() == name) {
2225 Session::diskstream_by_id (id_t id)
2227 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2229 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2230 if ((*i)->id() == id) {
2238 /* AudioRegion management */
2241 Session::new_region_name (string old)
2243 string::size_type last_period;
2245 string::size_type len = old.length() + 64;
2248 if ((last_period = old.find_last_of ('.')) == string::npos) {
2250 /* no period present - add one explicitly */
2253 last_period = old.length() - 1;
2258 number = atoi (old.substr (last_period+1).c_str());
2262 while (number < (UINT_MAX-1)) {
2264 AudioRegionList::const_iterator i;
2269 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2272 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2273 if ((*i).second->name() == sbuf) {
2278 if (i == audio_regions.end()) {
2283 if (number != (UINT_MAX-1)) {
2287 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2292 Session::region_name (string& result, string base, bool newlevel) const
2299 LockMonitor lm (region_lock, __LINE__, __FILE__);
2301 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2309 /* XXX this is going to be slow. optimize me later */
2314 string::size_type pos;
2316 if ((pos = base.find_last_of ('-')) == string::npos) {
2317 pos = base.find_last_of ('.');
2320 /* pos may be npos, but then we just use entire base */
2322 subbase = base.substr (0, pos);
2325 bool name_taken = true;
2328 LockMonitor lm (region_lock, __LINE__, __FILE__);
2330 for (int n = 1; n < 5000; ++n) {
2333 snprintf (buf, sizeof (buf), ".%d", n);
2338 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2339 if ((*i).second->name() == result) {
2352 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2361 Session::add_region (Region* region)
2363 AudioRegion* ar = 0;
2364 AudioRegion* oar = 0;
2368 LockMonitor lm (region_lock, __LINE__, __FILE__);
2370 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2372 AudioRegionList::iterator x;
2374 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2376 oar = dynamic_cast<AudioRegion*> (x->second);
2378 if (ar->region_list_equivalent (*oar)) {
2383 if (x == audio_regions.end()) {
2385 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2387 entry.first = region->id();
2390 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2401 fatal << _("programming error: ")
2402 << X_("unknown region type passed to Session::add_region()")
2409 /* mark dirty because something has changed even if we didn't
2410 add the region to the region list.
2416 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2417 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2418 AudioRegionAdded (ar); /* EMIT SIGNAL */
2423 Session::region_changed (Change what_changed, Region* region)
2425 if (what_changed & Region::HiddenChanged) {
2426 /* relay hidden changes */
2427 RegionHiddenChange (region);
2432 Session::region_renamed (Region* region)
2434 add_region (region);
2438 Session::remove_region (Region* region)
2440 AudioRegionList::iterator i;
2441 AudioRegion* ar = 0;
2442 bool removed = false;
2445 LockMonitor lm (region_lock, __LINE__, __FILE__);
2447 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2448 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2449 audio_regions.erase (i);
2453 fatal << _("programming error: ")
2454 << X_("unknown region type passed to Session::remove_region()")
2460 /* mark dirty because something has changed even if we didn't
2461 remove the region from the region list.
2467 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2472 Session::find_whole_file_parent (AudioRegion& child)
2474 AudioRegionList::iterator i;
2475 AudioRegion* region;
2476 LockMonitor lm (region_lock, __LINE__, __FILE__);
2478 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2480 region = (*i).second;
2482 if (region->whole_file()) {
2484 if (child.source_equivalent (*region)) {
2494 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2496 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2500 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2504 pl->get_region_list_equivalent_regions (region, result);
2509 Session::destroy_region (Region* region)
2511 AudioRegion* aregion;
2513 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2517 if (aregion->playlist()) {
2518 aregion->playlist()->destroy_region (region);
2521 vector<Source*> srcs;
2523 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2524 srcs.push_back (&aregion->source (n));
2527 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2529 if ((*i)->use_cnt() == 0) {
2530 (*i)->mark_for_remove ();
2539 Session::destroy_regions (list<Region*> regions)
2541 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2542 destroy_region (*i);
2548 Session::remove_last_capture ()
2552 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2554 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2555 list<Region*>& l = (*i)->last_capture_regions();
2558 r.insert (r.end(), l.begin(), l.end());
2563 destroy_regions (r);
2568 Session::remove_region_from_region_list (Region& r)
2574 /* Source Management */
2577 Session::add_source (Source* source)
2579 pair<SourceList::key_type, SourceList::mapped_type> entry;
2582 LockMonitor lm (source_lock, __LINE__, __FILE__);
2583 entry.first = source->id();
2584 entry.second = source;
2585 sources.insert (entry);
2588 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2591 SourceAdded (source); /* EMIT SIGNAL */
2595 Session::remove_source (Source* source)
2597 SourceList::iterator i;
2600 LockMonitor lm (source_lock, __LINE__, __FILE__);
2602 if ((i = sources.find (source->id())) != sources.end()) {
2607 if (!_state_of_the_state & InCleanup) {
2609 /* save state so we don't end up with a session file
2610 referring to non-existent sources.
2613 save_state (_current_snapshot_name);
2616 SourceRemoved(source); /* EMIT SIGNAL */
2620 Session::get_source (ARDOUR::id_t id)
2622 LockMonitor lm (source_lock, __LINE__, __FILE__);
2623 SourceList::iterator i;
2626 if ((i = sources.find (id)) != sources.end()) {
2627 source = (*i).second;
2634 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2638 char buf[PATH_MAX+1];
2639 const uint32_t limit = 10000;
2643 legalized = legalize_for_path (ds.name());
2645 /* find a "version" of the file name that doesn't exist in
2646 any of the possible directories.
2649 for (cnt = 1; cnt <= limit; ++cnt) {
2651 vector<space_and_path>::iterator i;
2652 uint32_t existing = 0;
2654 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2657 spath += sound_dir_name;
2661 if (ds.n_channels() < 2) {
2662 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2663 } else if (ds.n_channels() == 2) {
2665 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2667 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2669 } else if (ds.n_channels() < 26) {
2670 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2672 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2675 if (access (buf, F_OK) == 0) {
2680 if (existing == 0) {
2686 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
2687 throw failed_constructor();
2690 /* we now have a unique name for the file, but figure out where to
2696 spath = discover_best_sound_dir ();
2698 string::size_type pos = foo.find_last_of ('/');
2700 if (pos == string::npos) {
2703 spath += foo.substr (pos + 1);
2706 /* this might throw failed_constructor(), which is OK */
2709 return new DestructiveFileSource (spath, frame_rate());
2711 return new FileSource (spath, frame_rate());
2715 /* Playlist management */
2718 Session::get_playlist (string name)
2722 if ((ret = playlist_by_name (name)) == 0) {
2723 ret = new AudioPlaylist (*this, name);
2730 Session::playlist_by_name (string name)
2732 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2733 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2734 if ((*i)->name() == name) {
2738 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2739 if ((*i)->name() == name) {
2747 Session::add_playlist (Playlist* playlist)
2749 if (playlist->hidden()) {
2754 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2755 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2756 playlists.insert (playlists.begin(), playlist);
2758 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2759 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2765 PlaylistAdded (playlist); /* EMIT SIGNAL */
2769 Session::track_playlist (Playlist* pl, bool inuse)
2771 PlaylistList::iterator x;
2774 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2777 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2779 unused_playlists.insert (pl);
2781 if ((x = playlists.find (pl)) != playlists.end()) {
2782 playlists.erase (x);
2787 //cerr << "shifting playlist to used: " << pl->name() << endl;
2789 playlists.insert (pl);
2791 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2792 unused_playlists.erase (x);
2799 Session::remove_playlist (Playlist* playlist)
2801 if (_state_of_the_state & Deletion) {
2806 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2807 // cerr << "removing playlist: " << playlist->name() << endl;
2809 PlaylistList::iterator i;
2811 i = find (playlists.begin(), playlists.end(), playlist);
2813 if (i != playlists.end()) {
2814 playlists.erase (i);
2817 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2818 if (i != unused_playlists.end()) {
2819 unused_playlists.erase (i);
2826 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2830 Session::set_audition (AudioRegion* r)
2832 pending_audition_region = r;
2833 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2834 schedule_butler_transport_work ();
2838 Session::non_realtime_set_audition ()
2840 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
2841 auditioner->audition_current_playlist ();
2842 } else if (pending_audition_region) {
2843 auditioner->audition_region (*pending_audition_region);
2845 pending_audition_region = 0;
2846 AuditionActive (true); /* EMIT SIGNAL */
2850 Session::audition_playlist ()
2852 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2853 ev->set_ptr ((void*) 0xfeedface);
2858 Session::audition_region (AudioRegion& r)
2860 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2866 Session::cancel_audition ()
2868 if (auditioner->active()) {
2869 auditioner->cancel_audition ();
2870 AuditionActive (false); /* EMIT SIGNAL */
2875 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
2877 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
2881 Session::remove_empty_sounds ()
2884 PathScanner scanner;
2889 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
2891 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
2893 if (FileSource::is_empty (*(*i))) {
2895 unlink ((*i)->c_str());
2897 string peak_path = peak_path_from_audio_path (**i);
2898 unlink (peak_path.c_str());
2904 delete possible_audiofiles;
2908 Session::is_auditioning () const
2910 /* can be called before we have an auditioner object */
2912 return auditioner->active();
2920 Session::peak_path_from_audio_path (string audio_path)
2922 /* XXX hardly bombproof! fix me */
2926 res = PBD::dirname (audio_path);
2927 res = PBD::dirname (res);
2929 res += peak_dir_name;
2931 res += PBD::basename_nosuffix (audio_path);
2938 Session::old_peak_path_from_audio_path (string audio_path)
2940 /* This is a hangover from when audio and peak files
2941 lived in the same directory. We need it to to
2942 be able to open old sessions.
2945 /* XXX hardly bombproof! fix me */
2947 string res = audio_path.substr (0, audio_path.find_last_of ('.'));
2953 Session::set_all_solo (bool yn)
2956 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2958 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2959 if (!(*i)->hidden()) {
2960 (*i)->set_solo (yn, this);
2969 Session::set_all_mute (bool yn)
2972 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2974 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2975 if (!(*i)->hidden()) {
2976 (*i)->set_mute (yn, this);
2985 Session::n_diskstreams () const
2987 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2990 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2991 if (!(*i)->hidden()) {
2999 Session::foreach_diskstream (void (DiskStream::*func)(void))
3001 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3002 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3003 if (!(*i)->hidden()) {
3010 Session::graph_reordered ()
3012 /* don't do this stuff if we are setting up connections
3013 from a set_state() call.
3016 if (_state_of_the_state & InitialConnecting) {
3020 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3021 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3025 /* force all diskstreams to update their capture offset values to
3026 reflect any changes in latencies within the graph.
3029 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3030 (*i)->set_capture_offset ();
3035 Session::record_disenable_all ()
3037 record_enable_change_all (false);
3041 Session::record_enable_all ()
3043 record_enable_change_all (true);
3047 Session::record_enable_change_all (bool yn)
3049 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3051 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3054 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3055 at->set_record_enable (yn, this);
3059 /* since we don't keep rec-enable state, don't mark session dirty */
3063 Session::add_redirect (Redirect* redirect)
3067 PortInsert* port_insert;
3068 PluginInsert* plugin_insert;
3070 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3071 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3072 _port_inserts.insert (_port_inserts.begin(), port_insert);
3073 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3074 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3076 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3079 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3080 _sends.insert (_sends.begin(), send);
3082 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3086 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3092 Session::remove_redirect (Redirect* redirect)
3096 PortInsert* port_insert;
3097 PluginInsert* plugin_insert;
3099 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3100 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3101 _port_inserts.remove (port_insert);
3102 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3103 _plugin_inserts.remove (plugin_insert);
3105 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3108 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3109 _sends.remove (send);
3111 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3119 Session::available_capture_duration ()
3121 const double scale = 4096.0 / sizeof (Sample);
3123 if (_total_free_4k_blocks * scale > (double) max_frames) {
3127 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3131 Session::add_connection (ARDOUR::Connection* connection)
3134 LockMonitor (connection_lock, __LINE__, __FILE__);
3135 _connections.push_back (connection);
3138 ConnectionAdded (connection); /* EMIT SIGNAL */
3144 Session::remove_connection (ARDOUR::Connection* connection)
3146 bool removed = false;
3149 LockMonitor (connection_lock, __LINE__, __FILE__);
3150 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3152 if (i != _connections.end()) {
3153 _connections.erase (i);
3159 ConnectionRemoved (connection); /* EMIT SIGNAL */
3165 ARDOUR::Connection *
3166 Session::connection_by_name (string name) const
3168 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3170 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3171 if ((*i)->name() == name) {
3180 Session::set_edit_mode (EditMode mode)
3185 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3187 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3188 (*i)->set_edit_mode (mode);
3193 ControlChanged (EditingMode); /* EMIT SIGNAL */
3197 Session::tempo_map_changed (Change ignored)
3204 Session::ensure_passthru_buffers (uint32_t howmany)
3206 while (howmany > _passthru_buffers.size()) {
3208 #ifdef NO_POSIX_MEMALIGN
3209 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3211 posix_memalign((void **)&p,16,current_block_size * 4);
3213 _passthru_buffers.push_back (p);
3217 #ifdef NO_POSIX_MEMALIGN
3218 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3220 posix_memalign((void **)&p,16,current_block_size * 4);
3222 memset (p, 0, sizeof (Sample) * current_block_size);
3223 _silent_buffers.push_back (p);
3226 allocate_pan_automation_buffers (current_block_size, howmany, false);
3230 Session::next_send_name ()
3233 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3238 Session::next_insert_name ()
3241 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3245 /* Named Selection management */
3248 Session::named_selection_by_name (string name)
3250 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3251 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3252 if ((*i)->name == name) {
3260 Session::add_named_selection (NamedSelection* named_selection)
3263 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3264 named_selections.insert (named_selections.begin(), named_selection);
3269 NamedSelectionAdded (); /* EMIT SIGNAL */
3273 Session::remove_named_selection (NamedSelection* named_selection)
3275 bool removed = false;
3278 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3280 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3282 if (i != named_selections.end()) {
3284 named_selections.erase (i);
3291 NamedSelectionRemoved (); /* EMIT SIGNAL */
3296 Session::reset_native_file_format ()
3298 // jlc - WHY take routelock?
3299 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3300 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3302 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3303 (*i)->reset_write_sources (false);
3308 Session::route_name_unique (string n) const
3310 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3312 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3313 if ((*i)->name() == n) {
3322 Session::remove_file_source (FileSource& fs)
3324 return fs.move_to_trash (dead_sound_dir_name);
3328 Session::n_playlists () const
3330 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3331 return playlists.size();
3335 Session::set_solo_model (SoloModel sm)
3337 if (sm != _solo_model) {
3339 ControlChanged (SoloingModel);
3345 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3347 if (!force && howmany <= _npan_buffers) {
3351 if (_pan_automation_buffer) {
3353 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3354 delete [] _pan_automation_buffer[i];
3357 delete [] _pan_automation_buffer;
3360 _pan_automation_buffer = new pan_t*[howmany];
3362 for (uint32_t i = 0; i < howmany; ++i) {
3363 _pan_automation_buffer[i] = new pan_t[nframes];
3366 _npan_buffers = howmany;
3370 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3372 Stateful::add_instant_xml (node, dir);
3373 Config->add_instant_xml (node, Config->get_user_ardour_path());
3377 Session::freeze (InterThreadInfo& itt)
3379 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3381 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3385 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3386 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3397 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3398 InterThreadInfo& itt)
3402 FileSource* fsource;
3404 char buf[PATH_MAX+1];
3407 jack_nframes_t position;
3408 jack_nframes_t this_chunk;
3409 jack_nframes_t to_do;
3410 vector<Sample*> buffers;
3411 const jack_nframes_t chunk_size = (256 * 1024)/4;
3413 atomic_set (&processing_prohibited, 1);
3415 /* call tree *MUST* hold route_lock */
3417 if ((playlist = track.disk_stream().playlist()) == 0) {
3421 /* external redirects will be a problem */
3423 if (track.has_external_redirects()) {
3427 nchans = track.disk_stream().n_channels();
3429 dir = discover_best_sound_dir ();
3431 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3433 for (x = 0; x < 99999; ++x) {
3434 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3435 if (access (buf, F_OK) != 0) {
3441 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3446 fsource = new FileSource (buf, frame_rate());
3449 catch (failed_constructor& err) {
3450 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3454 srcs.push_back(fsource);
3457 /* XXX need to flush all redirects */
3462 /* create a set of reasonably-sized buffers */
3464 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3466 #ifdef NO_POSIX_MEMALIGN
3467 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3469 posix_memalign((void **)&b,16,chunk_size * 4);
3471 buffers.push_back (b);
3474 while (to_do && !itt.cancel) {
3476 this_chunk = min (to_do, chunk_size);
3478 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3483 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3484 if ((*src)->write (buffers[n], this_chunk) != this_chunk) {
3489 start += this_chunk;
3490 to_do -= this_chunk;
3492 itt.progress = (float) (1.0 - ((double) to_do / len));
3501 xnow = localtime (&now);
3503 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3504 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3507 /* build peakfile for new source */
3509 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3510 dynamic_cast<FileSource*>(*src)->build_peaks ();
3518 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3519 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3524 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3528 atomic_set (&processing_prohibited, 0);
3536 Session::get_silent_buffers (uint32_t howmany)
3538 for (uint32_t i = 0; i < howmany; ++i) {
3539 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3541 return _silent_buffers;
3545 Session::ntracks () const
3548 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3550 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3551 if (dynamic_cast<AudioTrack*> (*i)) {
3560 Session::nbusses () const
3563 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3565 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3566 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3575 Session::set_layer_model (LayerModel lm)
3577 if (lm != layer_model) {
3580 ControlChanged (LayeringModel);
3585 Session::set_xfade_model (CrossfadeModel xm)
3587 if (xm != xfade_model) {
3590 ControlChanged (CrossfadingModel);