2 Copyright (C) 1999-2010 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.
20 #define __STDC_LIMIT_MACROS
28 #include <cstdio> /* sprintf(3) ... grrr */
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include "pbd/boost_debug.h"
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
45 #include "pbd/convert.h"
47 #include "ardour/amp.h"
48 #include "ardour/analyser.h"
49 #include "ardour/audio_buffer.h"
50 #include "ardour/audio_diskstream.h"
51 #include "ardour/audio_port.h"
52 #include "ardour/audio_track.h"
53 #include "ardour/audioengine.h"
54 #include "ardour/audiofilesource.h"
55 #include "ardour/audioplaylist.h"
56 #include "ardour/audioregion.h"
57 #include "ardour/auditioner.h"
58 #include "ardour/buffer_manager.h"
59 #include "ardour/buffer_set.h"
60 #include "ardour/bundle.h"
61 #include "ardour/butler.h"
62 #include "ardour/click.h"
63 #include "ardour/configuration.h"
64 #include "ardour/crossfade.h"
65 #include "ardour/cycle_timer.h"
66 #include "ardour/data_type.h"
67 #include "ardour/debug.h"
68 #include "ardour/filename_extensions.h"
69 #include "ardour/internal_send.h"
70 #include "ardour/io_processor.h"
71 #include "ardour/midi_diskstream.h"
72 #include "ardour/midi_playlist.h"
73 #include "ardour/midi_region.h"
74 #include "ardour/midi_track.h"
75 #include "ardour/midi_ui.h"
76 #include "ardour/named_selection.h"
77 #include "ardour/process_thread.h"
78 #include "ardour/playlist.h"
79 #include "ardour/plugin_insert.h"
80 #include "ardour/port_insert.h"
81 #include "ardour/processor.h"
82 #include "ardour/rc_configuration.h"
83 #include "ardour/recent_sessions.h"
84 #include "ardour/region_factory.h"
85 #include "ardour/return.h"
86 #include "ardour/route_group.h"
87 #include "ardour/send.h"
88 #include "ardour/session.h"
89 #include "ardour/session_directory.h"
90 #include "ardour/session_directory.h"
91 #include "ardour/session_metadata.h"
92 #include "ardour/session_playlists.h"
93 #include "ardour/slave.h"
94 #include "ardour/smf_source.h"
95 #include "ardour/source_factory.h"
96 #include "ardour/tape_file_matcher.h"
97 #include "ardour/tempo.h"
98 #include "ardour/utils.h"
99 #include "ardour/graph.h"
101 #include "midi++/jack.h"
106 using namespace ARDOUR
;
108 using boost::shared_ptr
;
109 using boost::weak_ptr
;
111 bool Session::_disable_all_loaded_plugins
= false;
113 PBD::Signal1
<void,std::string
> Session::Dialog
;
114 PBD::Signal0
<int> Session::AskAboutPendingState
;
115 PBD::Signal2
<int,nframes_t
,nframes_t
> Session::AskAboutSampleRateMismatch
;
116 PBD::Signal0
<void> Session::SendFeedback
;
118 PBD::Signal0
<void> Session::TimecodeOffsetChanged
;
119 PBD::Signal0
<void> Session::StartTimeChanged
;
120 PBD::Signal0
<void> Session::EndTimeChanged
;
121 PBD::Signal0
<void> Session::AutoBindingOn
;
122 PBD::Signal0
<void> Session::AutoBindingOff
;
123 PBD::Signal2
<void,std::string
, std::string
> Session::Exported
;
124 PBD::Signal1
<int,boost::shared_ptr
<Playlist
> > Session::AskAboutPlaylistDeletion
;
126 static void clean_up_session_event (SessionEvent
* ev
) { delete ev
; }
127 const SessionEvent::RTeventCallback
Session::rt_cleanup (clean_up_session_event
);
129 Session::Session (AudioEngine
&eng
,
130 const string
& fullpath
,
131 const string
& snapshot_name
,
132 BusProfile
* bus_profile
,
136 _target_transport_speed (0.0),
137 _requested_return_frame (-1),
139 _mmc_port (default_mmc_port
),
140 _mtc_port (default_mtc_port
),
141 _midi_port (default_midi_port
),
142 _midi_clock_port (default_midi_clock_port
),
143 _session_dir (new SessionDirectory(fullpath
)),
145 _butler (new Butler (*this)),
146 _post_transport_work (0),
147 _send_timecode_update (false),
148 route_graph (new Graph(*this)),
149 routes (new RouteList
),
150 _total_free_4k_blocks (0),
151 _bundles (new BundleList
),
152 _bundle_xml_node (0),
155 click_emphasis_data (0),
157 _metadata (new SessionMetadata()),
158 _have_rec_enabled_track (false)
161 playlists
.reset (new SessionPlaylists
);
163 interpolation
.add_channel_to (0, 0);
165 if (!eng
.connected()) {
166 throw failed_constructor();
169 n_physical_outputs
= _engine
.n_physical_outputs(DataType::AUDIO
);
170 n_physical_inputs
= _engine
.n_physical_inputs(DataType::AUDIO
);
172 first_stage_init (fullpath
, snapshot_name
);
174 _is_new
= !Glib::file_test (_path
, Glib::FileTest (G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
));
177 if (create (mix_template
, bus_profile
)) {
179 throw failed_constructor ();
183 if (second_stage_init ()) {
185 throw failed_constructor ();
188 store_recent_sessions(_name
, _path
);
190 bool was_dirty
= dirty();
192 _state_of_the_state
= StateOfTheState (_state_of_the_state
& ~Dirty
);
194 Config
->ParameterChanged
.connect_same_thread (*this, boost::bind (&Session::config_changed
, this, _1
, false));
195 config
.ParameterChanged
.connect_same_thread (*this, boost::bind (&Session::config_changed
, this, _1
, true));
198 DirtyChanged (); /* EMIT SIGNAL */
212 vector
<void*> debug_pointers
;
214 /* if we got to here, leaving pending capture state around
218 remove_pending_capture_state ();
220 _state_of_the_state
= StateOfTheState (CannotSave
|Deletion
);
222 _engine
.remove_session ();
224 /* clear history so that no references to objects are held any more */
228 /* clear state tree so that no references to objects are held any more */
232 /* reset dynamic state version back to default */
234 Stateful::loading_state_version
= 0;
236 _butler
->drop_references ();
238 delete midi_control_ui
;
240 if (click_data
!= default_click
) {
241 delete [] click_data
;
244 if (click_emphasis_data
!= default_click_emphasis
) {
245 delete [] click_emphasis_data
;
250 /* clear out any pending dead wood from RCU managed objects */
255 AudioDiskstream::free_working_buffers();
257 /* tell everyone who is still standing that we're about to die */
260 /* tell everyone to drop references and delete objects as we go */
262 DEBUG_TRACE (DEBUG::Destruction
, "delete named selections\n");
263 named_selections
.clear ();
265 DEBUG_TRACE (DEBUG::Destruction
, "delete regions\n");
266 RegionFactory::delete_all_regions ();
268 DEBUG_TRACE (DEBUG::Destruction
, "delete routes\n");
270 /* reset these three references to special routes before we do the usual route delete thing */
273 _master_out
.reset ();
274 _monitor_out
.reset ();
277 RCUWriter
<RouteList
> writer (routes
);
278 boost::shared_ptr
<RouteList
> r
= writer
.get_copy ();
280 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
281 DEBUG_TRACE(DEBUG::Destruction
, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i
)->name(), (*i
).use_count()));
282 (*i
)->drop_references ();
286 /* writer goes out of scope and updates master */
290 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
292 DEBUG_TRACE (DEBUG::Destruction
, "delete sources\n");
293 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
294 DEBUG_TRACE(DEBUG::Destruction
, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i
->second
->path(), i
->second
.use_count()));
295 i
->second
->drop_references ();
300 DEBUG_TRACE (DEBUG::Destruction
, "delete route groups\n");
301 for (list
<RouteGroup
*>::iterator i
= _route_groups
.begin(); i
!= _route_groups
.end(); ++i
) {
306 Crossfade::set_buffer_size (0);
310 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
313 boost_debug_list_ptrs ();
315 DEBUG_TRACE (DEBUG::Destruction
, "Session::destroy() done\n");
319 Session::set_worst_io_latencies ()
321 _worst_output_latency
= 0;
322 _worst_input_latency
= 0;
324 if (!_engine
.connected()) {
328 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
330 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
331 _worst_output_latency
= max (_worst_output_latency
, (*i
)->output()->latency());
332 _worst_input_latency
= max (_worst_input_latency
, (*i
)->input()->latency());
337 Session::when_engine_running ()
339 string first_physical_output
;
341 BootMessage (_("Set block size and sample rate"));
343 set_block_size (_engine
.frames_per_cycle());
344 set_frame_rate (_engine
.frame_rate());
346 BootMessage (_("Using configuration"));
348 boost::function
<void (std::string
)> ff (boost::bind (&Session::config_changed
, this, _1
, false));
349 boost::function
<void (std::string
)> ft (boost::bind (&Session::config_changed
, this, _1
, true));
351 Config
->map_parameters (ff
);
352 config
.map_parameters (ft
);
354 /* every time we reconnect, recompute worst case output latencies */
356 _engine
.Running
.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies
, this));
358 if (synced_to_jack()) {
359 _engine
.transport_stop ();
362 if (config
.get_jack_time_master()) {
363 _engine
.transport_locate (_transport_frame
);
371 _click_io
.reset (new ClickIO (*this, "click"));
373 if (state_tree
&& (child
= find_named_node (*state_tree
->root(), "Click")) != 0) {
375 /* existing state for Click */
378 if (Stateful::loading_state_version
< 3000) {
379 c
= _click_io
->set_state_2X (*child
->children().front(), Stateful::loading_state_version
, false);
381 c
= _click_io
->set_state (*child
->children().front(), Stateful::loading_state_version
);
386 _clicking
= Config
->get_clicking ();
390 error
<< _("could not setup Click I/O") << endmsg
;
397 /* default state for Click: dual-mono to first 2 physical outputs */
399 for (int physport
= 0; physport
< 2; ++physport
) {
400 string physical_output
= _engine
.get_nth_physical_output (DataType::AUDIO
, physport
);
402 if (physical_output
.length()) {
403 if (_click_io
->add_port (physical_output
, this)) {
404 // relax, even though its an error
409 if (_click_io
->n_ports () > ChanCount::ZERO
) {
410 _clicking
= Config
->get_clicking ();
415 catch (failed_constructor
& err
) {
416 error
<< _("cannot setup Click I/O") << endmsg
;
419 BootMessage (_("Compute I/O Latencies"));
421 set_worst_io_latencies ();
424 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
427 BootMessage (_("Set up standard connections"));
429 /* Create a set of Bundle objects that map
430 to the physical I/O currently available. We create both
431 mono and stereo bundles, so that the common cases of mono
432 and stereo tracks get bundles to put in their mixer strip
433 in / out menus. There may be a nicer way of achieving that;
434 it doesn't really scale that well to higher channel counts
437 /* mono output bundles */
439 for (uint32_t np
= 0; np
< n_physical_outputs
; ++np
) {
441 snprintf (buf
, sizeof (buf
), _("out %" PRIu32
), np
+1);
443 shared_ptr
<Bundle
> c (new Bundle (buf
, true));
444 c
->add_channel (_("mono"));
445 c
->set_port (0, _engine
.get_nth_physical_output (DataType::AUDIO
, np
));
450 /* stereo output bundles */
452 for (uint32_t np
= 0; np
< n_physical_outputs
; np
+= 2) {
453 if (np
+ 1 < n_physical_outputs
) {
455 snprintf (buf
, sizeof(buf
), _("out %" PRIu32
"+%" PRIu32
), np
+ 1, np
+ 2);
456 shared_ptr
<Bundle
> c (new Bundle (buf
, true));
457 c
->add_channel (_("L"));
458 c
->set_port (0, _engine
.get_nth_physical_output (DataType::AUDIO
, np
));
459 c
->add_channel (_("R"));
460 c
->set_port (1, _engine
.get_nth_physical_output (DataType::AUDIO
, np
+ 1));
466 /* mono input bundles */
468 for (uint32_t np
= 0; np
< n_physical_inputs
; ++np
) {
470 snprintf (buf
, sizeof (buf
), _("in %" PRIu32
), np
+1);
472 shared_ptr
<Bundle
> c (new Bundle (buf
, false));
473 c
->add_channel (_("mono"));
474 c
->set_port (0, _engine
.get_nth_physical_input (DataType::AUDIO
, np
));
479 /* stereo input bundles */
481 for (uint32_t np
= 0; np
< n_physical_inputs
; np
+= 2) {
482 if (np
+ 1 < n_physical_inputs
) {
484 snprintf (buf
, sizeof(buf
), _("in %" PRIu32
"+%" PRIu32
), np
+ 1, np
+ 2);
486 shared_ptr
<Bundle
> c (new Bundle (buf
, false));
487 c
->add_channel (_("L"));
488 c
->set_port (0, _engine
.get_nth_physical_input (DataType::AUDIO
, np
));
489 c
->add_channel (_("R"));
490 c
->set_port (1, _engine
.get_nth_physical_input (DataType::AUDIO
, np
+ 1));
496 BootMessage (_("Setup signal flow and plugins"));
500 if (_is_new
&& !no_auto_connect()) {
502 /* don't connect the master bus outputs if there is a monitor bus */
504 if (_master_out
&& Config
->get_auto_connect_standard_busses() && !_monitor_out
) {
506 /* if requested auto-connect the outputs to the first N physical ports.
509 uint32_t limit
= _master_out
->n_outputs().n_total();
511 for (uint32_t n
= 0; n
< limit
; ++n
) {
512 Port
* p
= _master_out
->output()->nth (n
);
513 string connect_to
= _engine
.get_nth_physical_output (DataType (p
->type()), n
);
515 if (!connect_to
.empty() && p
->connected_to (connect_to
) == false) {
516 if (_master_out
->output()->connect (p
, connect_to
, this)) {
517 error
<< string_compose (_("cannot connect master output %1 to %2"), n
, connect_to
)
527 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
528 are undefined, at best.
531 /* control out listens to master bus (but ignores it
532 under some conditions)
535 uint32_t limit
= _monitor_out
->n_inputs().n_audio();
538 for (uint32_t n
= 0; n
< limit
; ++n
) {
539 AudioPort
* p
= _monitor_out
->input()->ports().nth_audio_port (n
);
540 AudioPort
* o
= _master_out
->output()->ports().nth_audio_port (n
);
543 string connect_to
= o
->name();
544 if (_monitor_out
->input()->connect (p
, connect_to
, this)) {
545 error
<< string_compose (_("cannot connect control input %1 to %2"), n
, connect_to
)
553 /* if control out is not connected, connect control out to physical outs
556 if (!_monitor_out
->output()->connected ()) {
558 if (!Config
->get_monitor_bus_preferred_bundle().empty()) {
560 boost::shared_ptr
<Bundle
> b
= bundle_by_name (Config
->get_monitor_bus_preferred_bundle());
563 _monitor_out
->output()->connect_ports_to_bundle (b
, this);
565 warning
<< string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
566 Config
->get_monitor_bus_preferred_bundle())
572 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
573 uint32_t mod
= _engine
.n_physical_outputs (*t
);
574 uint32_t limit
= _monitor_out
->n_outputs().get(*t
);
576 for (uint32_t n
= 0; n
< limit
; ++n
) {
578 Port
* p
= _monitor_out
->output()->ports().port(*t
, n
);
579 string connect_to
= _engine
.get_nth_physical_output (*t
, (n
% mod
));
581 if (!connect_to
.empty()) {
582 if (_monitor_out
->output()->connect (p
, connect_to
, this)) {
583 error
<< string_compose (
584 _("cannot connect control output %1 to %2"),
597 /* catch up on send+insert cnts */
599 _state_of_the_state
= StateOfTheState (_state_of_the_state
& ~(CannotSave
|Dirty
));
601 /* hook us up to the engine */
603 BootMessage (_("Connect to engine"));
605 _engine
.set_session (this);
609 Session::hookup_io ()
611 /* stop graph reordering notifications from
612 causing resorts, etc.
615 _state_of_the_state
= StateOfTheState (_state_of_the_state
| InitialConnecting
);
620 /* we delay creating the auditioner till now because
621 it makes its own connections to ports.
625 Auditioner
* a
= new Auditioner (*this);
628 throw failed_constructor();
630 a
->use_new_diskstream ();
631 auditioner
.reset (a
);
634 catch (failed_constructor
& err
) {
635 warning
<< _("cannot create Auditioner: no auditioning of regions possible") << endmsg
;
639 /* load bundles, which we may have postponed earlier on */
640 if (_bundle_xml_node
) {
641 load_bundles (*_bundle_xml_node
);
642 delete _bundle_xml_node
;
645 /* Tell all IO objects to connect themselves together */
647 IO::enable_connecting ();
648 MIDI::JACK_MidiPort::MakeConnections ();
650 /* Now reset all panners */
652 Delivery::reset_panners ();
654 /* Connect tracks to monitor/listen bus if there is one.
655 Note that in an existing session, the internal sends will
656 already exist, but we want the routes to notice that
657 they connect to the control out specifically.
661 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
662 for (RouteList::iterator x
= r
->begin(); x
!= r
->end(); ++x
) {
664 if ((*x
)->is_monitor()) {
668 } else if ((*x
)->is_master()) {
674 (*x
)->listen_via (_monitor_out
,
675 (Config
->get_listen_position() == AfterFaderListen
? PostFader
: PreFader
),
681 /* Anyone who cares about input state, wake up and do something */
683 IOConnectionsComplete (); /* EMIT SIGNAL */
685 _state_of_the_state
= StateOfTheState (_state_of_the_state
& ~InitialConnecting
);
687 /* now handle the whole enchilada as if it was one
693 /* update the full solo state, which can't be
694 correctly determined on a per-route basis, but
695 needs the global overview that only the session
699 update_route_solo_state ();
703 Session::playlist_length_changed ()
705 update_session_range_location_marker ();
709 Session::track_playlist_changed (boost::weak_ptr
<Track
> wp
)
711 boost::shared_ptr
<Track
> track
= wp
.lock ();
716 boost::shared_ptr
<Playlist
> playlist
;
718 if ((playlist
= track
->playlist()) != 0) {
719 playlist
->LengthChanged
.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed
, this));
722 update_session_range_location_marker ();
726 Session::record_enabling_legal () const
728 /* this used to be in here, but survey says.... we don't need to restrict it */
729 // if (record_status() == Recording) {
733 if (Config
->get_all_safe()) {
740 Session::reset_input_monitor_state ()
742 if (transport_rolling()) {
744 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
745 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
746 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
747 if (tr
&& tr
->record_enabled ()) {
748 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
749 tr
->monitor_input (Config
->get_monitoring_model() == HardwareMonitoring
&& !config
.get_auto_input());
755 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
756 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
757 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
758 if (tr
&& tr
->record_enabled ()) {
759 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
760 tr
->monitor_input (Config
->get_monitoring_model() == HardwareMonitoring
);
767 Session::auto_punch_start_changed (Location
* location
)
769 replace_event (SessionEvent::PunchIn
, location
->start());
771 if (get_record_enabled() && config
.get_punch_in()) {
772 /* capture start has been changed, so save new pending state */
773 save_state ("", true);
778 Session::auto_punch_end_changed (Location
* location
)
780 nframes_t when_to_stop
= location
->end();
781 // when_to_stop += _worst_output_latency + _worst_input_latency;
782 replace_event (SessionEvent::PunchOut
, when_to_stop
);
786 Session::auto_punch_changed (Location
* location
)
788 nframes_t when_to_stop
= location
->end();
790 replace_event (SessionEvent::PunchIn
, location
->start());
791 //when_to_stop += _worst_output_latency + _worst_input_latency;
792 replace_event (SessionEvent::PunchOut
, when_to_stop
);
796 Session::auto_loop_changed (Location
* location
)
798 replace_event (SessionEvent::AutoLoop
, location
->end(), location
->start());
800 if (transport_rolling() && play_loop
) {
803 // if (_transport_frame > location->end()) {
805 if (_transport_frame
< location
->start() || _transport_frame
> location
->end()) {
806 // relocate to beginning of loop
807 clear_events (SessionEvent::LocateRoll
);
809 request_locate (location
->start(), true);
812 else if (Config
->get_seamless_loop() && !loop_changing
) {
814 // schedule a locate-roll to refill the diskstreams at the
816 loop_changing
= true;
818 if (location
->end() > last_loopend
) {
819 clear_events (SessionEvent::LocateRoll
);
820 SessionEvent
*ev
= new SessionEvent (SessionEvent::LocateRoll
, SessionEvent::Add
, last_loopend
, last_loopend
, 0, true);
827 last_loopend
= location
->end();
831 Session::set_auto_punch_location (Location
* location
)
835 if ((existing
= _locations
.auto_punch_location()) != 0 && existing
!= location
) {
836 punch_connections
.drop_connections();
837 existing
->set_auto_punch (false, this);
838 remove_event (existing
->start(), SessionEvent::PunchIn
);
839 clear_events (SessionEvent::PunchOut
);
840 auto_punch_location_changed (0);
849 if (location
->end() <= location
->start()) {
850 error
<< _("Session: you can't use that location for auto punch (start <= end)") << endmsg
;
854 punch_connections
.drop_connections ();
856 location
->start_changed
.connect_same_thread (punch_connections
, boost::bind (&Session::auto_punch_start_changed
, this, _1
));
857 location
->end_changed
.connect_same_thread (punch_connections
, boost::bind (&Session::auto_punch_end_changed
, this, _1
));
858 location
->changed
.connect_same_thread (punch_connections
, boost::bind (&Session::auto_punch_changed
, this, _1
));
860 location
->set_auto_punch (true, this);
862 auto_punch_changed (location
);
864 auto_punch_location_changed (location
);
868 Session::set_auto_loop_location (Location
* location
)
872 if ((existing
= _locations
.auto_loop_location()) != 0 && existing
!= location
) {
873 loop_connections
.drop_connections ();
874 existing
->set_auto_loop (false, this);
875 remove_event (existing
->end(), SessionEvent::AutoLoop
);
876 auto_loop_location_changed (0);
885 if (location
->end() <= location
->start()) {
886 error
<< _("Session: you can't use a mark for auto loop") << endmsg
;
890 last_loopend
= location
->end();
892 loop_connections
.drop_connections ();
894 location
->start_changed
.connect_same_thread (loop_connections
, boost::bind (&Session::auto_loop_changed
, this, _1
));
895 location
->end_changed
.connect_same_thread (loop_connections
, boost::bind (&Session::auto_loop_changed
, this, _1
));
896 location
->changed
.connect_same_thread (loop_connections
, boost::bind (&Session::auto_loop_changed
, this, _1
));
898 location
->set_auto_loop (true, this);
900 /* take care of our stuff first */
902 auto_loop_changed (location
);
904 /* now tell everyone else */
906 auto_loop_location_changed (location
);
910 Session::locations_added (Location
*)
916 Session::locations_changed ()
918 _locations
.apply (*this, &Session::handle_locations_changed
);
922 Session::handle_locations_changed (Locations::LocationList
& locations
)
924 Locations::LocationList::iterator i
;
926 bool set_loop
= false;
927 bool set_punch
= false;
929 for (i
= locations
.begin(); i
!= locations
.end(); ++i
) {
933 if (location
->is_auto_punch()) {
934 set_auto_punch_location (location
);
937 if (location
->is_auto_loop()) {
938 set_auto_loop_location (location
);
942 if (location
->is_session_range()) {
943 _session_range_location
= location
;
948 set_auto_loop_location (0);
951 set_auto_punch_location (0);
958 Session::enable_record ()
960 /* XXX really atomic compare+swap here */
961 if (g_atomic_int_get (&_record_status
) != Recording
) {
962 g_atomic_int_set (&_record_status
, Recording
);
963 _last_record_location
= _transport_frame
;
964 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe
, _last_record_location
);
966 if (Config
->get_monitoring_model() == HardwareMonitoring
&& config
.get_auto_input()) {
968 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
969 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
970 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
971 if (tr
&& tr
->record_enabled ()) {
972 tr
->monitor_input (true);
977 RecordStateChanged ();
982 Session::disable_record (bool rt_context
, bool force
)
986 if ((rs
= (RecordState
) g_atomic_int_get (&_record_status
)) != Disabled
) {
988 if ((!Config
->get_latched_record_enable () && !play_loop
) || force
) {
989 g_atomic_int_set (&_record_status
, Disabled
);
991 if (rs
== Recording
) {
992 g_atomic_int_set (&_record_status
, Enabled
);
996 // FIXME: timestamp correct? [DR]
997 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
998 // does this /need/ to be sent in all cases?
1000 deliver_mmc (MIDI::MachineControl::cmdRecordExit
, _transport_frame
);
1003 if (Config
->get_monitoring_model() == HardwareMonitoring
&& config
.get_auto_input()) {
1005 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
1006 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
1007 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
1008 if (tr
&& tr
->record_enabled ()) {
1009 tr
->monitor_input (false);
1014 RecordStateChanged (); /* emit signal */
1017 remove_pending_capture_state ();
1023 Session::step_back_from_record ()
1025 if (g_atomic_int_compare_and_exchange (&_record_status
, Recording
, Enabled
)) {
1027 if (Config
->get_monitoring_model() == HardwareMonitoring
&& config
.get_auto_input()) {
1028 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
1029 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
1030 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
1031 if (tr
&& tr
->record_enabled ()) {
1032 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1033 tr
->monitor_input (false);
1041 Session::maybe_enable_record ()
1043 g_atomic_int_set (&_record_status
, Enabled
);
1045 /* this function is currently called from somewhere other than an RT thread.
1046 this save_state() call therefore doesn't impact anything.
1049 save_state ("", true);
1051 if (_transport_speed
) {
1052 if (!config
.get_punch_in()) {
1056 deliver_mmc (MIDI::MachineControl::cmdRecordPause
, _transport_frame
);
1057 RecordStateChanged (); /* EMIT SIGNAL */
1064 Session::audible_frame () const
1070 /* the first of these two possible settings for "offset"
1071 mean that the audible frame is stationary until
1072 audio emerges from the latency compensation
1075 the second means that the audible frame is stationary
1076 until audio would emerge from a physical port
1077 in the absence of any plugin latency compensation
1080 offset
= _worst_output_latency
;
1082 if (offset
> current_block_size
) {
1083 offset
-= current_block_size
;
1085 /* XXX is this correct? if we have no external
1086 physical connections and everything is internal
1087 then surely this is zero? still, how
1088 likely is that anyway?
1090 offset
= current_block_size
;
1093 if (synced_to_jack()) {
1094 tf
= _engine
.transport_frame();
1096 tf
= _transport_frame
;
1101 if (!non_realtime_work_pending()) {
1105 /* Check to see if we have passed the first guaranteed
1106 audible frame past our last start position. if not,
1107 return that last start point because in terms
1108 of audible frames, we have not moved yet.
1110 `Start position' in this context means the time we last
1111 either started or changed transport direction.
1114 if (_transport_speed
> 0.0f
) {
1116 if (!play_loop
|| !have_looped
) {
1117 if (tf
< _last_roll_or_reversal_location
+ offset
) {
1118 return _last_roll_or_reversal_location
;
1126 } else if (_transport_speed
< 0.0f
) {
1128 /* XXX wot? no backward looping? */
1130 if (tf
> _last_roll_or_reversal_location
- offset
) {
1131 return _last_roll_or_reversal_location
;
1143 Session::set_frame_rate (nframes_t frames_per_second
)
1145 /** \fn void Session::set_frame_size(nframes_t)
1146 the AudioEngine object that calls this guarantees
1147 that it will not be called while we are also in
1148 ::process(). Its fine to do things that block
1152 _base_frame_rate
= frames_per_second
;
1156 Automatable::set_automation_interval ((jack_nframes_t
) ceil ((double) frames_per_second
* (0.001 * Config
->get_automation_interval())));
1160 // XXX we need some equivalent to this, somehow
1161 // SndFileSource::setup_standard_crossfades (frames_per_second);
1165 /* XXX need to reset/reinstantiate all LADSPA plugins */
1169 Session::set_block_size (nframes_t nframes
)
1171 /* the AudioEngine guarantees
1172 that it will not be called while we are also in
1173 ::process(). It is therefore fine to do things that block
1178 current_block_size
= nframes
;
1182 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1184 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1185 (*i
)->set_block_size (nframes
);
1188 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
1189 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
1190 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
1192 tr
->set_block_size (nframes
);
1196 set_worst_io_latencies ();
1201 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1204 nframes_t fade_frames
;
1206 /* Don't allow fade of less 1 frame */
1208 if (fade_msecs
< (1000.0 * (1.0/_current_frame_rate
))) {
1215 fade_frames
= (nframes_t
) floor (fade_msecs
* _current_frame_rate
* 0.001);
1219 default_fade_msecs
= fade_msecs
;
1220 default_fade_steepness
= steepness
;
1223 // jlc, WTF is this!
1224 Glib::RWLock::ReaderLock
lm (route_lock
);
1225 AudioRegion::set_default_fade (steepness
, fade_frames
);
1230 /* XXX have to do this at some point */
1231 /* foreach region using default fade, reset, then
1232 refill_all_diskstream_buffers ();
1237 struct RouteSorter
{
1238 bool operator() (boost::shared_ptr
<Route
> r1
, boost::shared_ptr
<Route
> r2
) {
1239 if (r2
->feeds (r1
)) {
1241 } else if (r1
->feeds (r2
)) {
1244 if (r1
->not_fed ()) {
1245 if (r2
->not_fed ()) {
1246 /* no ardour-based connections inbound to either route. just use signal order */
1247 return r1
->order_key(N_("signal")) < r2
->order_key(N_("signal"));
1249 /* r2 has connections, r1 does not; run r1 early */
1253 return r1
->order_key(N_("signal")) < r2
->order_key(N_("signal"));
1260 trace_terminal (shared_ptr
<Route
> r1
, shared_ptr
<Route
> rbase
)
1262 shared_ptr
<Route
> r2
;
1264 if (r1
->feeds (rbase
) && rbase
->feeds (r1
)) {
1265 info
<< string_compose(_("feedback loop setup between %1 and %2"), r1
->name(), rbase
->name()) << endmsg
;
1269 /* make a copy of the existing list of routes that feed r1 */
1271 Route::FedBy
existing (r1
->fed_by());
1273 /* for each route that feeds r1, recurse, marking it as feeding
1277 for (Route::FedBy::iterator i
= existing
.begin(); i
!= existing
.end(); ++i
) {
1278 if (!(r2
= i
->r
.lock ())) {
1279 /* (*i) went away, ignore it */
1283 /* r2 is a route that feeds r1 which somehow feeds base. mark
1284 base as being fed by r2
1287 rbase
->add_fed_by (r2
, i
->sends_only
);
1291 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1295 if (r1
->feeds (r2
) && r2
->feeds (r1
)) {
1299 /* now recurse, so that we can mark base as being fed by
1300 all routes that feed r2
1303 trace_terminal (r2
, rbase
);
1310 Session::resort_routes ()
1312 /* don't do anything here with signals emitted
1313 by Routes while we are being destroyed.
1316 if (_state_of_the_state
& Deletion
) {
1321 RCUWriter
<RouteList
> writer (routes
);
1322 shared_ptr
<RouteList
> r
= writer
.get_copy ();
1323 resort_routes_using (r
);
1324 /* writer goes out of scope and forces update */
1327 //route_graph->dump(1);
1330 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
1331 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
1332 DEBUG_TRACE (DEBUG::Graph
, string_compose ("%1 fed by ...\n", (*i
)->name()));
1334 const Route::FedBy
& fb ((*i
)->fed_by());
1336 for (Route::FedBy::const_iterator f
= fb
.begin(); f
!= fb
.end(); ++f
) {
1337 boost::shared_ptr
<Route
> sf
= f
->r
.lock();
1339 DEBUG_TRACE (DEBUG::Graph
, string_compose ("\t%1 (sends only ? %2)\n", sf
->name(), f
->sends_only
));
1347 Session::resort_routes_using (shared_ptr
<RouteList
> r
)
1349 RouteList::iterator i
, j
;
1351 for (i
= r
->begin(); i
!= r
->end(); ++i
) {
1353 (*i
)->clear_fed_by ();
1355 for (j
= r
->begin(); j
!= r
->end(); ++j
) {
1357 /* although routes can feed themselves, it will
1358 cause an endless recursive descent if we
1359 detect it. so don't bother checking for
1367 bool via_sends_only
;
1369 if ((*j
)->direct_feeds (*i
, &via_sends_only
)) {
1370 (*i
)->add_fed_by (*j
, via_sends_only
);
1375 for (i
= r
->begin(); i
!= r
->end(); ++i
) {
1376 trace_terminal (*i
, *i
);
1382 route_graph
->rechain (r
);
1385 DEBUG_TRACE (DEBUG::Graph
, "Routes resorted, order follows:\n");
1386 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1387 DEBUG_TRACE (DEBUG::Graph
, string_compose ("\t%1 signal order %2\n",
1388 (*i
)->name(), (*i
)->order_key ("signal")));
1394 /** Find the route name starting with \a base with the lowest \a id.
1396 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1397 * The available route name with the lowest ID will be used, and \a id
1398 * will be set to the ID.
1400 * \return false if a route name could not be found, and \a track_name
1401 * and \a id do not reflect a free route name.
1404 Session::find_route_name (const char* base
, uint32_t& id
, char* name
, size_t name_len
)
1407 snprintf (name
, name_len
, "%s %" PRIu32
, base
, id
);
1409 if (route_by_name (name
) == 0) {
1415 } while (id
< (UINT_MAX
-1));
1421 Session::count_existing_route_channels (ChanCount
& in
, ChanCount
& out
)
1423 in
= ChanCount::ZERO
;
1424 out
= ChanCount::ZERO
;
1425 shared_ptr
<RouteList
> r
= routes
.reader ();
1426 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1427 if (!(*i
)->is_hidden()) {
1428 in
+= (*i
)->n_inputs();
1429 out
+= (*i
)->n_outputs();
1434 list
<boost::shared_ptr
<MidiTrack
> >
1435 Session::new_midi_track (TrackMode mode
, RouteGroup
* route_group
, uint32_t how_many
)
1437 char track_name
[32];
1438 uint32_t track_id
= 0;
1439 ChanCount existing_inputs
;
1440 ChanCount existing_outputs
;
1442 RouteList new_routes
;
1443 list
<boost::shared_ptr
<MidiTrack
> > ret
;
1444 uint32_t control_id
;
1446 count_existing_route_channels (existing_inputs
, existing_outputs
);
1448 control_id
= ntracks() + nbusses();
1451 if (!find_route_name ("Midi", ++track_id
, track_name
, sizeof(track_name
))) {
1452 error
<< "cannot find name for new midi track" << endmsg
;
1456 shared_ptr
<MidiTrack
> track
;
1459 MidiTrack
* mt
= new MidiTrack (*this, track_name
, Route::Flag (0), mode
);
1466 mt
->use_new_diskstream();
1468 boost_debug_shared_ptr_mark_interesting (mt
, "Track");
1469 track
= boost::shared_ptr
<MidiTrack
>(mt
);
1471 if (track
->input()->ensure_io (ChanCount(DataType::MIDI
, 1), false, this)) {
1472 error
<< "cannot configure 1 in/1 out configuration for new midi track" << endmsg
;
1477 if (track
->output()->ensure_io (ChanCount(DataType::MIDI
, 1), false, this)) {
1478 error
<< "cannot configure 1 in/1 out configuration for new midi track" << endmsg
;
1482 auto_connect_route (track
, existing_inputs
, existing_outputs
);
1484 track
->non_realtime_input_change();
1487 route_group
->add (track
);
1490 track
->DiskstreamChanged
.connect_same_thread (*this, boost::bind (&Session::resort_routes
, this));
1491 track
->set_remote_control_id (control_id
);
1493 new_routes
.push_back (track
);
1494 ret
.push_back (track
);
1497 catch (failed_constructor
&err
) {
1498 error
<< _("Session: could not create new midi track.") << endmsg
;
1502 catch (AudioEngine::PortRegistrationFailure
& pfe
) {
1504 error
<< string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME
) << endmsg
;
1512 if (!new_routes
.empty()) {
1513 add_routes (new_routes
, false);
1514 save_state (_current_snapshot_name
);
1521 Session::auto_connect_route (boost::shared_ptr
<Route
> route
,
1522 ChanCount
& existing_inputs
, ChanCount
& existing_outputs
)
1524 /* If both inputs and outputs are auto-connected to physical ports,
1525 use the max of input and output offsets to ensure auto-connected
1526 port numbers always match up (e.g. the first audio input and the
1527 first audio output of the route will have the same physical
1528 port number). Otherwise just use the lowest input or output
1531 const bool in_out_physical
=
1532 (Config
->get_input_auto_connect() & AutoConnectPhysical
)
1533 && (Config
->get_output_auto_connect() & AutoConnectPhysical
);
1535 const ChanCount in_offset
= in_out_physical
1536 ? ChanCount::max(existing_inputs
, existing_outputs
)
1539 const ChanCount out_offset
= in_out_physical
1540 ? ChanCount::max(existing_inputs
, existing_outputs
)
1543 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
1544 vector
<string
> physinputs
;
1545 vector
<string
> physoutputs
;
1547 _engine
.get_physical_outputs (*t
, physoutputs
);
1548 _engine
.get_physical_inputs (*t
, physinputs
);
1550 if (!physinputs
.empty()) {
1551 uint32_t nphysical_in
= physinputs
.size();
1552 for (uint32_t i
= 0; i
< route
->n_inputs().get(*t
) && i
< nphysical_in
; ++i
) {
1555 if (Config
->get_input_auto_connect() & AutoConnectPhysical
) {
1556 port
= physinputs
[(in_offset
.get(*t
) + i
) % nphysical_in
];
1559 if (!port
.empty() && route
->input()->connect (
1560 route
->input()->ports().port(*t
, i
), port
, this)) {
1566 if (!physoutputs
.empty()) {
1567 uint32_t nphysical_out
= physoutputs
.size();
1568 for (uint32_t i
= 0; i
< route
->n_outputs().get(*t
); ++i
) {
1571 if (Config
->get_output_auto_connect() & AutoConnectPhysical
) {
1572 port
= physoutputs
[(out_offset
.get(*t
) + i
) % nphysical_out
];
1573 } else if (Config
->get_output_auto_connect() & AutoConnectMaster
) {
1574 if (_master_out
&& _master_out
->n_inputs().get(*t
) > 0) {
1575 port
= _master_out
->input()->ports().port(*t
,
1576 i
% _master_out
->input()->n_ports().get(*t
))->name();
1580 if (!port
.empty() && route
->output()->connect (
1581 route
->output()->ports().port(*t
, i
), port
, this)) {
1588 existing_inputs
+= route
->n_inputs();
1589 existing_outputs
+= route
->n_outputs();
1592 list
< boost::shared_ptr
<AudioTrack
> >
1593 Session::new_audio_track (int input_channels
, int output_channels
, TrackMode mode
, RouteGroup
* route_group
, uint32_t how_many
)
1595 char track_name
[32];
1596 uint32_t track_id
= 0;
1597 ChanCount existing_inputs
;
1598 ChanCount existing_outputs
;
1600 RouteList new_routes
;
1601 list
<boost::shared_ptr
<AudioTrack
> > ret
;
1602 uint32_t control_id
;
1604 count_existing_route_channels (existing_inputs
, existing_outputs
);
1606 control_id
= ntracks() + nbusses() + 1;
1609 if (!find_route_name ("Audio", ++track_id
, track_name
, sizeof(track_name
))) {
1610 error
<< "cannot find name for new audio track" << endmsg
;
1614 shared_ptr
<AudioTrack
> track
;
1617 AudioTrack
* at
= new AudioTrack (*this, track_name
, Route::Flag (0), mode
);
1624 at
->use_new_diskstream();
1626 boost_debug_shared_ptr_mark_interesting (at
, "Track");
1627 track
= boost::shared_ptr
<AudioTrack
>(at
);
1629 if (track
->input()->ensure_io (ChanCount(DataType::AUDIO
, input_channels
), false, this)) {
1630 error
<< string_compose (
1631 _("cannot configure %1 in/%2 out configuration for new audio track"),
1632 input_channels
, output_channels
)
1637 if (track
->output()->ensure_io (ChanCount(DataType::AUDIO
, output_channels
), false, this)) {
1638 error
<< string_compose (
1639 _("cannot configure %1 in/%2 out configuration for new audio track"),
1640 input_channels
, output_channels
)
1645 auto_connect_route (track
, existing_inputs
, existing_outputs
);
1648 route_group
->add (track
);
1651 track
->non_realtime_input_change();
1653 track
->DiskstreamChanged
.connect_same_thread (*this, boost::bind (&Session::resort_routes
, this));
1654 track
->set_remote_control_id (control_id
);
1657 new_routes
.push_back (track
);
1658 ret
.push_back (track
);
1661 catch (failed_constructor
&err
) {
1662 error
<< _("Session: could not create new audio track.") << endmsg
;
1666 catch (AudioEngine::PortRegistrationFailure
& pfe
) {
1668 error
<< pfe
.what() << endmsg
;
1676 if (!new_routes
.empty()) {
1677 add_routes (new_routes
, true);
1684 Session::set_remote_control_ids ()
1686 RemoteModel m
= Config
->get_remote_model();
1687 bool emit_signal
= false;
1689 shared_ptr
<RouteList
> r
= routes
.reader ();
1691 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1692 if (MixerOrdered
== m
) {
1693 long order
= (*i
)->order_key(N_("signal"));
1694 (*i
)->set_remote_control_id (order
+1, false);
1696 } else if (EditorOrdered
== m
) {
1697 long order
= (*i
)->order_key(N_("editor"));
1698 (*i
)->set_remote_control_id (order
+1, false);
1700 } else if (UserOrdered
== m
) {
1701 //do nothing ... only changes to remote id's are initiated by user
1706 Route::RemoteControlIDChange();
1712 Session::new_audio_route (bool aux
, int input_channels
, int output_channels
, RouteGroup
* route_group
, uint32_t how_many
)
1715 uint32_t bus_id
= 0;
1716 ChanCount existing_inputs
;
1717 ChanCount existing_outputs
;
1720 uint32_t control_id
;
1722 count_existing_route_channels (existing_inputs
, existing_outputs
);
1724 control_id
= ntracks() + nbusses() + 1;
1727 if (!find_route_name ("Bus", ++bus_id
, bus_name
, sizeof(bus_name
))) {
1728 error
<< "cannot find name for new audio bus" << endmsg
;
1733 Route
* rt
= new Route (*this, bus_name
, Route::Flag(0), DataType::AUDIO
);
1740 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
1741 shared_ptr
<Route
> bus (rt
);
1743 if (bus
->input()->ensure_io (ChanCount(DataType::AUDIO
, input_channels
), false, this)) {
1744 error
<< string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1745 input_channels
, output_channels
)
1751 if (bus
->output()->ensure_io (ChanCount(DataType::AUDIO
, output_channels
), false, this)) {
1752 error
<< string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1753 input_channels
, output_channels
)
1758 auto_connect_route (bus
, existing_inputs
, existing_outputs
);
1761 route_group
->add (bus
);
1763 bus
->set_remote_control_id (control_id
);
1767 bus
->add_internal_return ();
1770 ret
.push_back (bus
);
1774 catch (failed_constructor
&err
) {
1775 error
<< _("Session: could not create new audio route.") << endmsg
;
1779 catch (AudioEngine::PortRegistrationFailure
& pfe
) {
1780 error
<< pfe
.what() << endmsg
;
1790 add_routes (ret
, true);
1798 Session::new_route_from_template (uint32_t how_many
, const std::string
& template_path
)
1802 uint32_t control_id
;
1804 uint32_t number
= 0;
1806 if (!tree
.read (template_path
.c_str())) {
1810 XMLNode
* node
= tree
.root();
1812 control_id
= ntracks() + nbusses() + 1;
1816 XMLNode
node_copy (*node
); // make a copy so we can change the name if we need to
1818 std::string node_name
= IO::name_from_state (*node_copy
.children().front());
1820 /* generate a new name by adding a number to the end of the template name */
1821 if (!find_route_name (node_name
.c_str(), ++number
, name
, sizeof(name
))) {
1822 fatal
<< _("Session: UINT_MAX routes? impossible!") << endmsg
;
1826 /* set IO children to use the new name */
1827 XMLNodeList
const & children
= node_copy
.children ();
1828 for (XMLNodeList::const_iterator i
= children
.begin(); i
!= children
.end(); ++i
) {
1829 if ((*i
)->name() == IO::state_node_name
) {
1830 IO::set_name_in_state (**i
, name
);
1834 Track::zero_diskstream_id_in_xml (node_copy
);
1837 shared_ptr
<Route
> route (XMLRouteFactory (node_copy
, 3000));
1840 error
<< _("Session: cannot create track/bus from template description") << endmsg
;
1844 if (boost::dynamic_pointer_cast
<Track
>(route
)) {
1845 /* force input/output change signals so that the new diskstream
1846 picks up the configuration of the route. During session
1847 loading this normally happens in a different way.
1849 route
->input()->changed (IOChange (ConfigurationChanged
|ConnectionsChanged
), this);
1850 route
->output()->changed (IOChange (ConfigurationChanged
|ConnectionsChanged
), this);
1853 route
->set_remote_control_id (control_id
);
1856 ret
.push_back (route
);
1859 catch (failed_constructor
&err
) {
1860 error
<< _("Session: could not create new route from template") << endmsg
;
1864 catch (AudioEngine::PortRegistrationFailure
& pfe
) {
1865 error
<< pfe
.what() << endmsg
;
1874 add_routes (ret
, true);
1881 Session::add_routes (RouteList
& new_routes
, bool save
)
1884 RCUWriter
<RouteList
> writer (routes
);
1885 shared_ptr
<RouteList
> r
= writer
.get_copy ();
1886 r
->insert (r
->end(), new_routes
.begin(), new_routes
.end());
1889 /* if there is no control out and we're not in the middle of loading,
1890 resort the graph here. if there is a control out, we will resort
1891 toward the end of this method. if we are in the middle of loading,
1892 we will resort when done.
1895 if (!_monitor_out
&& IO::connecting_legal
) {
1896 resort_routes_using (r
);
1900 for (RouteList::iterator x
= new_routes
.begin(); x
!= new_routes
.end(); ++x
) {
1902 boost::weak_ptr
<Route
> wpr (*x
);
1903 boost::shared_ptr
<Route
> r (*x
);
1905 r
->listen_changed
.connect_same_thread (*this, boost::bind (&Session::route_listen_changed
, this, _1
, wpr
));
1906 r
->solo_changed
.connect_same_thread (*this, boost::bind (&Session::route_solo_changed
, this, _1
, _2
, wpr
));
1907 r
->solo_isolated_changed
.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed
, this, _1
, wpr
));
1908 r
->mute_changed
.connect_same_thread (*this, boost::bind (&Session::route_mute_changed
, this, _1
));
1909 r
->output()->changed
.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x
, this, _1
, _2
));
1910 r
->processors_changed
.connect_same_thread (*this, boost::bind (&Session::route_processors_changed
, this, _1
));
1911 r
->route_group_changed
.connect_same_thread (*this, boost::bind (&Session::route_group_changed
, this));
1913 if (r
->is_master()) {
1917 if (r
->is_monitor()) {
1921 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (r
);
1923 tr
->PlaylistChanged
.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed
, this, boost::weak_ptr
<Track
> (tr
)));
1924 track_playlist_changed (boost::weak_ptr
<Track
> (tr
));
1925 tr
->RecordEnableChanged
.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track
, this));
1929 if (_monitor_out
&& IO::connecting_legal
) {
1931 for (RouteList::iterator x
= new_routes
.begin(); x
!= new_routes
.end(); ++x
) {
1932 if ((*x
)->is_monitor()) {
1934 } else if ((*x
)->is_master()) {
1937 (*x
)->listen_via (_monitor_out
,
1938 (Config
->get_listen_position() == AfterFaderListen
? PostFader
: PreFader
),
1949 save_state (_current_snapshot_name
);
1952 RouteAdded (new_routes
); /* EMIT SIGNAL */
1953 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
1957 Session::globally_set_send_gains_to_zero (boost::shared_ptr
<Route
> dest
)
1959 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1960 boost::shared_ptr
<Send
> s
;
1964 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1965 if (boost::dynamic_pointer_cast
<Track
>(*i
)) {
1966 if ((s
= (*i
)->internal_send_for (dest
)) != 0) {
1967 s
->amp()->gain_control()->set_value (0.0);
1974 Session::globally_set_send_gains_to_unity (boost::shared_ptr
<Route
> dest
)
1976 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1977 boost::shared_ptr
<Send
> s
;
1981 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1982 if (boost::dynamic_pointer_cast
<Track
>(*i
)) {
1983 if ((s
= (*i
)->internal_send_for (dest
)) != 0) {
1984 s
->amp()->gain_control()->set_value (1.0);
1991 Session::globally_set_send_gains_from_track(boost::shared_ptr
<Route
> dest
)
1993 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1994 boost::shared_ptr
<Send
> s
;
1998 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1999 if (boost::dynamic_pointer_cast
<Track
>(*i
)) {
2000 if ((s
= (*i
)->internal_send_for (dest
)) != 0) {
2001 s
->amp()->gain_control()->set_value ((*i
)->gain_control()->get_value());
2008 Session::globally_add_internal_sends (boost::shared_ptr
<Route
> dest
, Placement p
)
2010 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
2011 boost::shared_ptr
<RouteList
> t (new RouteList
);
2013 /* only send tracks */
2015 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2016 if (boost::dynamic_pointer_cast
<Track
>(*i
)) {
2021 add_internal_sends (dest
, p
, t
);
2025 Session::add_internal_sends (boost::shared_ptr
<Route
> dest
, Placement p
, boost::shared_ptr
<RouteList
> senders
)
2027 if (dest
->is_monitor() || dest
->is_master()) {
2031 if (!dest
->internal_return()) {
2032 dest
->add_internal_return();
2035 for (RouteList::iterator i
= senders
->begin(); i
!= senders
->end(); ++i
) {
2037 if ((*i
)->is_monitor() || (*i
)->is_master() || (*i
) == dest
) {
2041 (*i
)->listen_via (dest
, p
, true, true);
2048 Session::remove_route (shared_ptr
<Route
> route
)
2050 if (((route
== _master_out
) || (route
== _monitor_out
)) && !Config
->get_allow_special_bus_removal()) {
2055 RCUWriter
<RouteList
> writer (routes
);
2056 shared_ptr
<RouteList
> rs
= writer
.get_copy ();
2060 /* deleting the master out seems like a dumb
2061 idea, but its more of a UI policy issue
2065 if (route
== _master_out
) {
2066 _master_out
= shared_ptr
<Route
> ();
2069 if (route
== _monitor_out
) {
2071 /* cancel control outs for all routes */
2073 for (RouteList::iterator r
= rs
->begin(); r
!= rs
->end(); ++r
) {
2074 (*r
)->drop_listen (_monitor_out
);
2077 _monitor_out
.reset ();
2080 /* writer goes out of scope, forces route list update */
2083 update_route_solo_state ();
2084 update_session_range_location_marker ();
2086 // We need to disconnect the route's inputs and outputs
2088 route
->input()->disconnect (0);
2089 route
->output()->disconnect (0);
2091 /* if the route had internal sends sending to it, remove them */
2092 if (route
->internal_return()) {
2094 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
2095 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2096 boost::shared_ptr
<Send
> s
= (*i
)->internal_send_for (route
);
2098 (*i
)->remove_processor (s
);
2103 update_latency_compensation (false, false);
2106 /* flush references out of the graph
2109 route_graph
->clear_other_chain ();
2111 /* get rid of it from the dead wood collection in the route list manager */
2113 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2117 /* try to cause everyone to drop their references */
2119 route
->drop_references ();
2121 sync_order_keys (N_("session"));
2123 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2125 /* save the new state of the world */
2127 if (save_state (_current_snapshot_name
)) {
2128 save_history (_current_snapshot_name
);
2133 Session::route_mute_changed (void* /*src*/)
2139 Session::route_listen_changed (void* /*src*/, boost::weak_ptr
<Route
> wpr
)
2141 boost::shared_ptr
<Route
> route
= wpr
.lock();
2143 error
<< string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg
;
2147 if (route
->listening()) {
2149 if (Config
->get_exclusive_solo()) {
2150 /* new listen: disable all other listen */
2151 shared_ptr
<RouteList
> r
= routes
.reader ();
2152 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2153 if ((*i
) == route
|| (*i
)->solo_isolated() || (*i
)->is_master() || (*i
)->is_monitor() || (*i
)->is_hidden()) {
2156 (*i
)->set_listen (false, this);
2162 } else if (_listen_cnt
> 0) {
2168 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr
<Route
> wpr
)
2170 boost::shared_ptr
<Route
> route
= wpr
.lock ();
2173 /* should not happen */
2174 error
<< string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg
;
2178 bool send_changed
= false;
2180 if (route
->solo_isolated()) {
2181 if (_solo_isolated_cnt
== 0) {
2182 send_changed
= true;
2184 _solo_isolated_cnt
++;
2185 } else if (_solo_isolated_cnt
> 0) {
2186 _solo_isolated_cnt
--;
2187 if (_solo_isolated_cnt
== 0) {
2188 send_changed
= true;
2193 IsolatedChanged (); /* EMIT SIGNAL */
2198 Session::route_solo_changed (bool self_solo_change
, void* /*src*/, boost::weak_ptr
<Route
> wpr
)
2200 if (!self_solo_change
) {
2201 // session doesn't care about changes to soloed-by-others
2205 if (solo_update_disabled
) {
2210 boost::shared_ptr
<Route
> route
= wpr
.lock ();
2213 /* should not happen */
2214 error
<< string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg
;
2218 shared_ptr
<RouteList
> r
= routes
.reader ();
2221 if (route
->self_soloed()) {
2227 if (delta
== 1 && Config
->get_exclusive_solo()) {
2228 /* new solo: disable all other solos */
2229 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2230 if ((*i
) == route
|| (*i
)->solo_isolated() || (*i
)->is_master() || (*i
)->is_monitor() || (*i
)->is_hidden()) {
2233 (*i
)->set_solo (false, this);
2237 solo_update_disabled
= true;
2239 RouteList uninvolved
;
2241 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2242 bool via_sends_only
;
2243 bool in_signal_flow
;
2245 if ((*i
) == route
|| (*i
)->solo_isolated() || (*i
)->is_master() || (*i
)->is_monitor() || (*i
)->is_hidden()) {
2249 in_signal_flow
= false;
2251 if ((*i
)->feeds (route
, &via_sends_only
)) {
2252 if (!via_sends_only
) {
2253 if (!route
->soloed_by_others_upstream()) {
2254 (*i
)->mod_solo_by_others_downstream (delta
);
2256 in_signal_flow
= true;
2260 if (route
->feeds (*i
, &via_sends_only
)) {
2261 (*i
)->mod_solo_by_others_upstream (delta
);
2262 in_signal_flow
= true;
2265 if (!in_signal_flow
) {
2266 uninvolved
.push_back (*i
);
2270 solo_update_disabled
= false;
2271 update_route_solo_state (r
);
2273 /* now notify that the mute state of the routes not involved in the signal
2274 pathway of the just-solo-changed route may have altered.
2277 for (RouteList::iterator i
= uninvolved
.begin(); i
!= uninvolved
.end(); ++i
) {
2278 (*i
)->mute_changed (this);
2281 SoloChanged (); /* EMIT SIGNAL */
2286 Session::update_route_solo_state (boost::shared_ptr
<RouteList
> r
)
2288 /* now figure out if anything that matters is soloed (or is "listening")*/
2290 bool something_soloed
= false;
2291 uint32_t listeners
= 0;
2292 uint32_t isolated
= 0;
2295 r
= routes
.reader();
2298 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2299 if (!(*i
)->is_master() && !(*i
)->is_monitor() && !(*i
)->is_hidden() && (*i
)->self_soloed()) {
2300 something_soloed
= true;
2303 if (!(*i
)->is_hidden() && (*i
)->listening()) {
2304 if (Config
->get_solo_control_is_listen_control()) {
2307 (*i
)->set_listen (false, this);
2311 if ((*i
)->solo_isolated()) {
2316 if (something_soloed
!= _non_soloed_outs_muted
) {
2317 _non_soloed_outs_muted
= something_soloed
;
2318 SoloActive (_non_soloed_outs_muted
); /* EMIT SIGNAL */
2321 _listen_cnt
= listeners
;
2323 if (isolated
!= _solo_isolated_cnt
) {
2324 _solo_isolated_cnt
= isolated
;
2325 IsolatedChanged (); /* EMIT SIGNAL */
2329 boost::shared_ptr
<RouteList
>
2330 Session::get_routes_with_internal_returns() const
2332 shared_ptr
<RouteList
> r
= routes
.reader ();
2333 boost::shared_ptr
<RouteList
> rl (new RouteList
);
2335 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2336 if ((*i
)->internal_return ()) {
2344 Session::io_name_is_legal (const std::string
& name
)
2346 shared_ptr
<RouteList
> r
= routes
.reader ();
2348 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2349 if ((*i
)->name() == name
) {
2353 if ((*i
)->has_io_processor_named (name
)) {
2362 Session::route_by_name (string name
)
2364 shared_ptr
<RouteList
> r
= routes
.reader ();
2366 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2367 if ((*i
)->name() == name
) {
2372 return shared_ptr
<Route
> ((Route
*) 0);
2376 Session::route_by_id (PBD::ID id
)
2378 shared_ptr
<RouteList
> r
= routes
.reader ();
2380 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2381 if ((*i
)->id() == id
) {
2386 return shared_ptr
<Route
> ((Route
*) 0);
2390 Session::route_by_remote_id (uint32_t id
)
2392 shared_ptr
<RouteList
> r
= routes
.reader ();
2394 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
2395 if ((*i
)->remote_control_id() == id
) {
2400 return shared_ptr
<Route
> ((Route
*) 0);
2403 /** If either end of the session range location marker lies inside the current
2404 * session extent, move it to the corresponding session extent.
2407 Session::update_session_range_location_marker ()
2409 if (_state_of_the_state
& Loading
) {
2413 pair
<nframes_t
, nframes_t
> const ext
= get_extent ();
2415 if (_session_range_location
== 0) {
2416 /* we don't have a session range yet; use this one (provided it is valid) */
2417 if (ext
.first
!= max_frames
) {
2418 add_session_range_location (ext
.first
, ext
.second
);
2421 /* update the existing session range */
2422 if (ext
.first
< _session_range_location
->start()) {
2423 _session_range_location
->set_start (ext
.first
);
2427 if (ext
.second
> _session_range_location
->end()) {
2428 _session_range_location
->set_end (ext
.second
);
2435 /** @return Extent of the session's contents; if the session is empty, the first value of
2436 * the pair will equal max_frames.
2438 pair
<nframes_t
, nframes_t
>
2439 Session::get_extent () const
2441 pair
<nframes_t
, nframes_t
> ext (max_frames
, 0);
2443 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
2444 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
2445 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
2446 if (!tr
|| tr
->destructive()) {
2447 // ignore tape tracks when getting extents
2451 pair
<nframes_t
, nframes_t
> e
= tr
->playlist()->get_extent ();
2452 if (e
.first
< ext
.first
) {
2453 ext
.first
= e
.first
;
2455 if (e
.second
> ext
.second
) {
2456 ext
.second
= e
.second
;
2463 /* Region management */
2465 boost::shared_ptr
<Region
>
2466 Session::find_whole_file_parent (boost::shared_ptr
<Region
const> child
) const
2468 const RegionFactory::RegionMap
& regions (RegionFactory::regions());
2469 RegionFactory::RegionMap::const_iterator i
;
2470 boost::shared_ptr
<Region
> region
;
2472 Glib::Mutex::Lock
lm (region_lock
);
2474 for (i
= regions
.begin(); i
!= regions
.end(); ++i
) {
2478 if (region
->whole_file()) {
2480 if (child
->source_equivalent (region
)) {
2486 return boost::shared_ptr
<Region
> ();
2490 Session::destroy_sources (list
<boost::shared_ptr
<Source
> > srcs
)
2492 set
<boost::shared_ptr
<Region
> > relevant_regions
;
2494 for (list
<boost::shared_ptr
<Source
> >::iterator s
= srcs
.begin(); s
!= srcs
.end(); ++s
) {
2495 RegionFactory::get_regions_using_source (*s
, relevant_regions
);
2498 cerr
<< "There are " << relevant_regions
.size() << " using " << srcs
.size() << " sources" << endl
;
2500 for (set
<boost::shared_ptr
<Region
> >::iterator r
= relevant_regions
.begin(); r
!= relevant_regions
.end(); ) {
2501 set
<boost::shared_ptr
<Region
> >::iterator tmp
;
2506 cerr
<< "Cleanup " << (*r
)->name() << " UC = " << (*r
).use_count() << endl
;
2508 playlists
->destroy_region (*r
);
2509 RegionFactory::map_remove (*r
);
2511 (*r
)->drop_sources ();
2512 (*r
)->drop_references ();
2514 cerr
<< "\tdone UC = " << (*r
).use_count() << endl
;
2516 relevant_regions
.erase (r
);
2521 for (list
<boost::shared_ptr
<Source
> >::iterator s
= srcs
.begin(); s
!= srcs
.end(); ) {
2524 Glib::Mutex::Lock
ls (source_lock
);
2525 /* remove from the main source list */
2526 sources
.erase ((*s
)->id());
2529 (*s
)->mark_for_remove ();
2530 (*s
)->drop_references ();
2539 Session::remove_last_capture ()
2541 list
<boost::shared_ptr
<Source
> > srcs
;
2543 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
2544 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
2545 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
2550 list
<boost::shared_ptr
<Source
> >& l
= tr
->last_capture_sources();
2553 srcs
.insert (srcs
.end(), l
.begin(), l
.end());
2558 destroy_sources (srcs
);
2560 save_state (_current_snapshot_name
);
2565 /* Source Management */
2568 Session::add_source (boost::shared_ptr
<Source
> source
)
2570 pair
<SourceMap::key_type
, SourceMap::mapped_type
> entry
;
2571 pair
<SourceMap::iterator
,bool> result
;
2573 entry
.first
= source
->id();
2574 entry
.second
= source
;
2577 Glib::Mutex::Lock
lm (source_lock
);
2578 result
= sources
.insert (entry
);
2581 if (result
.second
) {
2583 /* yay, new source */
2587 boost::shared_ptr
<AudioFileSource
> afs
;
2589 if ((afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(source
)) != 0) {
2590 if (Config
->get_auto_analyse_audio()) {
2591 Analyser::queue_source_for_analysis (source
, false);
2598 Session::remove_source (boost::weak_ptr
<Source
> src
)
2600 SourceMap::iterator i
;
2601 boost::shared_ptr
<Source
> source
= src
.lock();
2608 Glib::Mutex::Lock
lm (source_lock
);
2610 if ((i
= sources
.find (source
->id())) != sources
.end()) {
2615 if (!_state_of_the_state
& InCleanup
) {
2617 /* save state so we don't end up with a session file
2618 referring to non-existent sources.
2621 save_state (_current_snapshot_name
);
2625 boost::shared_ptr
<Source
>
2626 Session::source_by_id (const PBD::ID
& id
)
2628 Glib::Mutex::Lock
lm (source_lock
);
2629 SourceMap::iterator i
;
2630 boost::shared_ptr
<Source
> source
;
2632 if ((i
= sources
.find (id
)) != sources
.end()) {
2639 boost::shared_ptr
<Source
>
2640 Session::source_by_path_and_channel (const Glib::ustring
& path
, uint16_t chn
)
2642 Glib::Mutex::Lock
lm (source_lock
);
2644 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
2645 cerr
<< "comparing " << path
<< " with " << i
->second
->name() << endl
;
2646 boost::shared_ptr
<AudioFileSource
> afs
2647 = boost::dynamic_pointer_cast
<AudioFileSource
>(i
->second
);
2649 if (afs
&& afs
->path() == path
&& chn
== afs
->channel()) {
2653 return boost::shared_ptr
<Source
>();
2658 Session::change_source_path_by_name (string path
, string oldname
, string newname
, bool destructive
)
2661 string old_basename
= PBD::basename_nosuffix (oldname
);
2662 string new_legalized
= legalize_for_path (newname
);
2664 /* note: we know (or assume) the old path is already valid */
2668 /* destructive file sources have a name of the form:
2670 /path/to/Tnnnn-NAME(%[LR])?.wav
2672 the task here is to replace NAME with the new name.
2675 /* find last slash */
2679 string::size_type slash
;
2680 string::size_type dash
;
2682 if ((slash
= path
.find_last_of ('/')) == string::npos
) {
2686 dir
= path
.substr (0, slash
+1);
2688 /* '-' is not a legal character for the NAME part of the path */
2690 if ((dash
= path
.find_last_of ('-')) == string::npos
) {
2694 prefix
= path
.substr (slash
+1, dash
-(slash
+1));
2699 path
+= new_legalized
;
2700 path
+= ".wav"; /* XXX gag me with a spoon */
2704 /* non-destructive file sources have a name of the form:
2706 /path/to/NAME-nnnnn(%[LR])?.ext
2708 the task here is to replace NAME with the new name.
2713 string::size_type slash
;
2714 string::size_type dash
;
2715 string::size_type postfix
;
2717 /* find last slash */
2719 if ((slash
= path
.find_last_of ('/')) == string::npos
) {
2723 dir
= path
.substr (0, slash
+1);
2725 /* '-' is not a legal character for the NAME part of the path */
2727 if ((dash
= path
.find_last_of ('-')) == string::npos
) {
2731 suffix
= path
.substr (dash
+1);
2733 // Suffix is now everything after the dash. Now we need to eliminate
2734 // the nnnnn part, which is done by either finding a '%' or a '.'
2736 postfix
= suffix
.find_last_of ("%");
2737 if (postfix
== string::npos
) {
2738 postfix
= suffix
.find_last_of ('.');
2741 if (postfix
!= string::npos
) {
2742 suffix
= suffix
.substr (postfix
);
2744 error
<< "Logic error in Session::change_source_path_by_name(), please report" << endl
;
2748 const uint32_t limit
= 10000;
2749 char buf
[PATH_MAX
+1];
2751 for (uint32_t cnt
= 1; cnt
<= limit
; ++cnt
) {
2753 snprintf (buf
, sizeof(buf
), "%s%s-%u%s", dir
.c_str(), newname
.c_str(), cnt
, suffix
.c_str());
2755 if (access (buf
, F_OK
) != 0) {
2763 error
<< "FATAL ERROR! Could not find a " << endl
;
2771 /** Return the full path (in some session directory) for a new within-session source.
2772 * \a name must be a session-unique name that does not contain slashes
2773 * (e.g. as returned by new_*_source_name)
2776 Session::new_source_path_from_name (DataType type
, const string
& name
)
2778 assert(name
.find("/") == string::npos
);
2780 SessionDirectory
sdir(get_best_session_directory_for_new_source());
2783 if (type
== DataType::AUDIO
) {
2784 p
= sdir
.sound_path();
2785 } else if (type
== DataType::MIDI
) {
2786 p
= sdir
.midi_path();
2788 error
<< "Unknown source type, unable to create file path" << endmsg
;
2793 return p
.to_string();
2797 Session::peak_path (Glib::ustring base
) const
2799 sys::path
peakfile_path(_session_dir
->peak_path());
2800 peakfile_path
/= basename_nosuffix (base
) + peakfile_suffix
;
2801 return peakfile_path
.to_string();
2804 /** Return a unique name based on \a base for a new internal audio source */
2806 Session::new_audio_source_name (const string
& base
, uint32_t nchan
, uint32_t chan
, bool destructive
)
2810 char buf
[PATH_MAX
+1];
2811 const uint32_t limit
= 10000;
2815 legalized
= legalize_for_path (base
);
2817 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2818 for (cnt
= (destructive
? ++destructive_index
: 1); cnt
<= limit
; ++cnt
) {
2820 vector
<space_and_path
>::iterator i
;
2821 uint32_t existing
= 0;
2823 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2825 SessionDirectory
sdir((*i
).path
);
2827 spath
= sdir
.sound_path().to_string();
2832 snprintf (buf
, sizeof(buf
), "%s/T%04d-%s.wav",
2833 spath
.c_str(), cnt
, legalized
.c_str());
2834 } else if (nchan
== 2) {
2836 snprintf (buf
, sizeof(buf
), "%s/T%04d-%s%%L.wav",
2837 spath
.c_str(), cnt
, legalized
.c_str());
2839 snprintf (buf
, sizeof(buf
), "%s/T%04d-%s%%R.wav",
2840 spath
.c_str(), cnt
, legalized
.c_str());
2842 } else if (nchan
< 26) {
2843 snprintf (buf
, sizeof(buf
), "%s/T%04d-%s%%%c.wav",
2844 spath
.c_str(), cnt
, legalized
.c_str(), 'a' + chan
);
2846 snprintf (buf
, sizeof(buf
), "%s/T%04d-%s.wav",
2847 spath
.c_str(), cnt
, legalized
.c_str());
2856 snprintf (buf
, sizeof(buf
), "%s-%u.wav", spath
.c_str(), cnt
);
2857 } else if (nchan
== 2) {
2859 snprintf (buf
, sizeof(buf
), "%s-%u%%L.wav", spath
.c_str(), cnt
);
2861 snprintf (buf
, sizeof(buf
), "%s-%u%%R.wav", spath
.c_str(), cnt
);
2863 } else if (nchan
< 26) {
2864 snprintf (buf
, sizeof(buf
), "%s-%u%%%c.wav", spath
.c_str(), cnt
, 'a' + chan
);
2866 snprintf (buf
, sizeof(buf
), "%s-%u.wav", spath
.c_str(), cnt
);
2870 if (sys::exists(buf
)) {
2876 if (existing
== 0) {
2881 error
<< string_compose(
2882 _("There are already %1 recordings for %2, which I consider too many."),
2883 limit
, base
) << endmsg
;
2885 throw failed_constructor();
2889 return Glib::path_get_basename(buf
);
2892 /** Create a new within-session audio source */
2893 boost::shared_ptr
<AudioFileSource
>
2894 Session::create_audio_source_for_session (size_t n_chans
, string
const & n
, uint32_t chan
, bool destructive
)
2896 const string name
= new_audio_source_name (n
, n_chans
, chan
, destructive
);
2897 const string path
= new_source_path_from_name(DataType::AUDIO
, name
);
2899 return boost::dynamic_pointer_cast
<AudioFileSource
> (
2900 SourceFactory::createWritable (DataType::AUDIO
, *this, path
, destructive
, frame_rate()));
2903 /** Return a unique name based on \a base for a new internal MIDI source */
2905 Session::new_midi_source_name (const string
& base
)
2908 char buf
[PATH_MAX
+1];
2909 const uint32_t limit
= 10000;
2913 legalized
= legalize_for_path (base
);
2915 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2916 for (cnt
= 1; cnt
<= limit
; ++cnt
) {
2918 vector
<space_and_path
>::iterator i
;
2919 uint32_t existing
= 0;
2921 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2923 SessionDirectory
sdir((*i
).path
);
2925 sys::path p
= sdir
.midi_path();
2928 snprintf (buf
, sizeof(buf
), "%s-%u.mid", p
.to_string().c_str(), cnt
);
2930 if (sys::exists (buf
)) {
2935 if (existing
== 0) {
2940 error
<< string_compose(
2941 _("There are already %1 recordings for %2, which I consider too many."),
2942 limit
, base
) << endmsg
;
2944 throw failed_constructor();
2948 return Glib::path_get_basename(buf
);
2952 /** Create a new within-session MIDI source */
2953 boost::shared_ptr
<MidiSource
>
2954 Session::create_midi_source_for_session (Track
* track
, string
const & n
)
2956 /* try to use the existing write source for the track, to keep numbering sane
2960 /*MidiTrack* mt = dynamic_cast<Track*> (track);
2964 list
<boost::shared_ptr
<Source
> > l
= track
->steal_write_sources ();
2967 assert (boost::dynamic_pointer_cast
<MidiSource
> (l
.front()));
2968 return boost::dynamic_pointer_cast
<MidiSource
> (l
.front());
2972 const string name
= new_midi_source_name (n
);
2973 const string path
= new_source_path_from_name (DataType::MIDI
, name
);
2975 return boost::dynamic_pointer_cast
<SMFSource
> (
2976 SourceFactory::createWritable (
2977 DataType::MIDI
, *this, path
, false, frame_rate()));
2982 Session::add_playlist (boost::shared_ptr
<Playlist
> playlist
, bool unused
)
2984 if (playlist
->hidden()) {
2988 playlists
->add (playlist
);
2991 playlist
->release();
2998 Session::remove_playlist (boost::weak_ptr
<Playlist
> weak_playlist
)
3000 if (_state_of_the_state
& Deletion
) {
3004 boost::shared_ptr
<Playlist
> playlist (weak_playlist
.lock());
3010 playlists
->remove (playlist
);
3016 Session::set_audition (boost::shared_ptr
<Region
> r
)
3018 pending_audition_region
= r
;
3019 add_post_transport_work (PostTransportAudition
);
3020 _butler
->schedule_transport_work ();
3024 Session::audition_playlist ()
3026 SessionEvent
* ev
= new SessionEvent (SessionEvent::Audition
, SessionEvent::Add
, SessionEvent::Immediate
, 0, 0.0);
3027 ev
->region
.reset ();
3032 Session::non_realtime_set_audition ()
3034 if (!pending_audition_region
) {
3035 auditioner
->audition_current_playlist ();
3037 auditioner
->audition_region (pending_audition_region
);
3038 pending_audition_region
.reset ();
3040 AuditionActive (true); /* EMIT SIGNAL */
3044 Session::audition_region (boost::shared_ptr
<Region
> r
)
3046 SessionEvent
* ev
= new SessionEvent (SessionEvent::Audition
, SessionEvent::Add
, SessionEvent::Immediate
, 0, 0.0);
3052 Session::cancel_audition ()
3054 if (auditioner
->auditioning()) {
3055 auditioner
->cancel_audition ();
3056 AuditionActive (false); /* EMIT SIGNAL */
3061 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr
<Route
> a
, boost::shared_ptr
<Route
> b
)
3063 if (a
->is_monitor()) {
3066 if (b
->is_monitor()) {
3069 return a
->order_key(N_("signal")) < b
->order_key(N_("signal"));
3073 Session::remove_empty_sounds ()
3075 vector
<string
> audio_filenames
;
3077 get_files_in_directory (_session_dir
->sound_path(), audio_filenames
);
3079 Glib::Mutex::Lock
lm (source_lock
);
3081 TapeFileMatcher tape_file_matcher
;
3083 remove_if (audio_filenames
.begin(), audio_filenames
.end(),
3084 boost::bind (&TapeFileMatcher::matches
, &tape_file_matcher
, _1
));
3086 for (vector
<string
>::iterator i
= audio_filenames
.begin(); i
!= audio_filenames
.end(); ++i
) {
3088 sys::path
audio_file_path (_session_dir
->sound_path());
3090 audio_file_path
/= *i
;
3092 if (AudioFileSource::is_empty (*this, audio_file_path
.to_string())) {
3096 sys::remove (audio_file_path
);
3097 const string peakfile
= peak_path (audio_file_path
.to_string());
3098 sys::remove (peakfile
);
3100 catch (const sys::filesystem_error
& err
)
3102 error
<< err
.what() << endmsg
;
3109 Session::is_auditioning () const
3111 /* can be called before we have an auditioner object */
3113 return auditioner
->auditioning();
3120 Session::graph_reordered ()
3122 /* don't do this stuff if we are setting up connections
3123 from a set_state() call or creating new tracks. Ditto for deletion.
3126 if (_state_of_the_state
& (InitialConnecting
|Deletion
)) {
3130 /* every track/bus asked for this to be handled but it was deferred because
3131 we were connecting. do it now.
3134 request_input_change_handling ();
3138 /* force all diskstreams to update their capture offset values to
3139 reflect any changes in latencies within the graph.
3142 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
3143 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
3144 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
3146 tr
->set_capture_offset ();
3152 Session::available_capture_duration ()
3154 float sample_bytes_on_disk
= 4.0; // keep gcc happy
3156 switch (config
.get_native_file_data_format()) {
3158 sample_bytes_on_disk
= 4.0;
3162 sample_bytes_on_disk
= 3.0;
3166 sample_bytes_on_disk
= 2.0;
3170 /* impossible, but keep some gcc versions happy */
3171 fatal
<< string_compose (_("programming error: %1"),
3172 X_("illegal native file data format"))
3177 double scale
= 4096.0 / sample_bytes_on_disk
;
3179 if (_total_free_4k_blocks
* scale
> (double) max_frames
) {
3183 return (nframes_t
) floor (_total_free_4k_blocks
* scale
);
3187 Session::add_bundle (shared_ptr
<Bundle
> bundle
)
3190 RCUWriter
<BundleList
> writer (_bundles
);
3191 boost::shared_ptr
<BundleList
> b
= writer
.get_copy ();
3192 b
->push_back (bundle
);
3195 BundleAdded (bundle
); /* EMIT SIGNAL */
3201 Session::remove_bundle (shared_ptr
<Bundle
> bundle
)
3203 bool removed
= false;
3206 RCUWriter
<BundleList
> writer (_bundles
);
3207 boost::shared_ptr
<BundleList
> b
= writer
.get_copy ();
3208 BundleList::iterator i
= find (b
->begin(), b
->end(), bundle
);
3210 if (i
!= b
->end()) {
3217 BundleRemoved (bundle
); /* EMIT SIGNAL */
3224 Session::bundle_by_name (string name
) const
3226 boost::shared_ptr
<BundleList
> b
= _bundles
.reader ();
3228 for (BundleList::const_iterator i
= b
->begin(); i
!= b
->end(); ++i
) {
3229 if ((*i
)->name() == name
) {
3234 return boost::shared_ptr
<Bundle
> ();
3238 Session::tempo_map_changed (const PropertyChange
&)
3242 playlists
->update_after_tempo_map_change ();
3247 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3248 * the given count with the current block size.
3251 Session::ensure_buffers (ChanCount howmany
)
3253 BufferManager::ensure_buffers (howmany
);
3257 Session::ensure_buffer_set(BufferSet
& buffers
, const ChanCount
& count
)
3259 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
3260 buffers
.ensure_buffers(*t
, count
.get(*t
), _engine
.raw_buffer_size(*t
));
3265 Session::next_insert_id ()
3267 /* this doesn't really loop forever. just think about it */
3270 for (boost::dynamic_bitset
<uint32_t>::size_type n
= 0; n
< insert_bitset
.size(); ++n
) {
3271 if (!insert_bitset
[n
]) {
3272 insert_bitset
[n
] = true;
3278 /* none available, so resize and try again */
3280 insert_bitset
.resize (insert_bitset
.size() + 16, false);
3285 Session::next_send_id ()
3287 /* this doesn't really loop forever. just think about it */
3290 for (boost::dynamic_bitset
<uint32_t>::size_type n
= 0; n
< send_bitset
.size(); ++n
) {
3291 if (!send_bitset
[n
]) {
3292 send_bitset
[n
] = true;
3298 /* none available, so resize and try again */
3300 send_bitset
.resize (send_bitset
.size() + 16, false);
3305 Session::next_return_id ()
3307 /* this doesn't really loop forever. just think about it */
3310 for (boost::dynamic_bitset
<uint32_t>::size_type n
= 0; n
< return_bitset
.size(); ++n
) {
3311 if (!return_bitset
[n
]) {
3312 return_bitset
[n
] = true;
3318 /* none available, so resize and try again */
3320 return_bitset
.resize (return_bitset
.size() + 16, false);
3325 Session::mark_send_id (uint32_t id
)
3327 if (id
>= send_bitset
.size()) {
3328 send_bitset
.resize (id
+16, false);
3330 if (send_bitset
[id
]) {
3331 warning
<< string_compose (_("send ID %1 appears to be in use already"), id
) << endmsg
;
3333 send_bitset
[id
] = true;
3337 Session::mark_return_id (uint32_t id
)
3339 if (id
>= return_bitset
.size()) {
3340 return_bitset
.resize (id
+16, false);
3342 if (return_bitset
[id
]) {
3343 warning
<< string_compose (_("return ID %1 appears to be in use already"), id
) << endmsg
;
3345 return_bitset
[id
] = true;
3349 Session::mark_insert_id (uint32_t id
)
3351 if (id
>= insert_bitset
.size()) {
3352 insert_bitset
.resize (id
+16, false);
3354 if (insert_bitset
[id
]) {
3355 warning
<< string_compose (_("insert ID %1 appears to be in use already"), id
) << endmsg
;
3357 insert_bitset
[id
] = true;
3361 Session::unmark_send_id (uint32_t id
)
3363 if (id
< send_bitset
.size()) {
3364 send_bitset
[id
] = false;
3369 Session::unmark_return_id (uint32_t id
)
3371 if (id
< return_bitset
.size()) {
3372 return_bitset
[id
] = false;
3377 Session::unmark_insert_id (uint32_t id
)
3379 if (id
< insert_bitset
.size()) {
3380 insert_bitset
[id
] = false;
3385 /* Named Selection management */
3387 boost::shared_ptr
<NamedSelection
>
3388 Session::named_selection_by_name (string name
)
3390 Glib::Mutex::Lock
lm (named_selection_lock
);
3391 for (NamedSelectionList::iterator i
= named_selections
.begin(); i
!= named_selections
.end(); ++i
) {
3392 if ((*i
)->name
== name
) {
3396 return boost::shared_ptr
<NamedSelection
>();
3400 Session::add_named_selection (boost::shared_ptr
<NamedSelection
> named_selection
)
3403 Glib::Mutex::Lock
lm (named_selection_lock
);
3404 named_selections
.insert (named_selections
.begin(), named_selection
);
3409 NamedSelectionAdded (); /* EMIT SIGNAL */
3413 Session::remove_named_selection (boost::shared_ptr
<NamedSelection
> named_selection
)
3415 bool removed
= false;
3418 Glib::Mutex::Lock
lm (named_selection_lock
);
3420 NamedSelectionList::iterator i
= find (named_selections
.begin(), named_selections
.end(), named_selection
);
3422 if (i
!= named_selections
.end()) {
3423 named_selections
.erase (i
);
3430 NamedSelectionRemoved (); /* EMIT SIGNAL */
3435 Session::reset_native_file_format ()
3437 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
3438 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
3439 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
3441 tr
->reset_write_sources (false);
3447 Session::route_name_unique (string n
) const
3449 shared_ptr
<RouteList
> r
= routes
.reader ();
3451 for (RouteList::const_iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3452 if ((*i
)->name() == n
) {
3461 Session::route_name_internal (string n
) const
3463 if (auditioner
&& auditioner
->name() == n
) {
3467 if (_click_io
&& _click_io
->name() == n
) {
3475 Session::freeze_all (InterThreadInfo
& itt
)
3477 shared_ptr
<RouteList
> r
= routes
.reader ();
3479 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3481 boost::shared_ptr
<Track
> t
;
3483 if ((t
= boost::dynamic_pointer_cast
<Track
>(*i
)) != 0) {
3484 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3494 boost::shared_ptr
<Region
>
3495 Session::write_one_track (AudioTrack
& track
, nframes_t start
, nframes_t end
,
3496 bool /*overwrite*/, vector
<boost::shared_ptr
<Source
> >& srcs
,
3497 InterThreadInfo
& itt
, bool enable_processing
)
3499 boost::shared_ptr
<Region
> result
;
3500 boost::shared_ptr
<Playlist
> playlist
;
3501 boost::shared_ptr
<AudioFileSource
> fsource
;
3503 char buf
[PATH_MAX
+1];
3504 ChanCount
nchans(track
.n_channels());
3506 nframes_t this_chunk
;
3509 SessionDirectory
sdir(get_best_session_directory_for_new_source ());
3510 const string sound_dir
= sdir
.sound_path().to_string();
3511 nframes_t len
= end
- start
;
3514 error
<< string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3515 end
, start
) << endmsg
;
3519 const nframes_t chunk_size
= (256 * 1024)/4;
3521 // block all process callback handling
3523 block_processing ();
3525 /* call tree *MUST* hold route_lock */
3527 if ((playlist
= track
.playlist()) == 0) {
3531 /* external redirects will be a problem */
3533 if (track
.has_external_redirects()) {
3537 for (uint32_t chan_n
=0; chan_n
< nchans
.n_audio(); ++chan_n
) {
3539 for (x
= 0; x
< 99999; ++x
) {
3540 snprintf (buf
, sizeof(buf
), "%s/%s-%d-bounce-%" PRIu32
".wav", sound_dir
.c_str(), playlist
->name().c_str(), chan_n
, x
+1);
3541 if (access (buf
, F_OK
) != 0) {
3547 error
<< string_compose (_("too many bounced versions of playlist \"%1\""), playlist
->name()) << endmsg
;
3552 fsource
= boost::dynamic_pointer_cast
<AudioFileSource
> (
3553 SourceFactory::createWritable (DataType::AUDIO
, *this, buf
, false, frame_rate()));
3556 catch (failed_constructor
& err
) {
3557 error
<< string_compose (_("cannot create new audio file \"%1\" for %2"), buf
, track
.name()) << endmsg
;
3561 srcs
.push_back (fsource
);
3564 /* XXX need to flush all redirects */
3569 /* create a set of reasonably-sized buffers */
3570 buffers
.ensure_buffers(DataType::AUDIO
, nchans
.n_audio(), chunk_size
);
3571 buffers
.set_count(nchans
);
3573 for (vector
<boost::shared_ptr
<Source
> >::iterator src
=srcs
.begin(); src
!= srcs
.end(); ++src
) {
3574 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(*src
);
3576 afs
->prepare_for_peakfile_writes ();
3579 while (to_do
&& !itt
.cancel
) {
3581 this_chunk
= min (to_do
, chunk_size
);
3583 if (track
.export_stuff (buffers
, start
, this_chunk
, enable_processing
)) {
3588 for (vector
<boost::shared_ptr
<Source
> >::iterator src
=srcs
.begin(); src
!= srcs
.end(); ++src
, ++n
) {
3589 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(*src
);
3592 if (afs
->write (buffers
.get_audio(n
).data(), this_chunk
) != this_chunk
) {
3598 start
+= this_chunk
;
3599 to_do
-= this_chunk
;
3601 itt
.progress
= (float) (1.0 - ((double) to_do
/ len
));
3610 xnow
= localtime (&now
);
3612 for (vector
<boost::shared_ptr
<Source
> >::iterator src
=srcs
.begin(); src
!= srcs
.end(); ++src
) {
3613 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(*src
);
3616 afs
->update_header (position
, *xnow
, now
);
3617 afs
->flush_header ();
3621 /* construct a region to represent the bounced material */
3625 plist
.add (Properties::start
, 0);
3626 plist
.add (Properties::length
, srcs
.front()->length(srcs
.front()->timeline_position()));
3627 plist
.add (Properties::name
, region_name_from_path (srcs
.front()->name(), true));
3629 result
= RegionFactory::create (srcs
, plist
);
3635 for (vector
<boost::shared_ptr
<Source
> >::iterator src
= srcs
.begin(); src
!= srcs
.end(); ++src
) {
3636 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(*src
);
3639 afs
->mark_for_remove ();
3642 (*src
)->drop_references ();
3646 for (vector
<boost::shared_ptr
<Source
> >::iterator src
= srcs
.begin(); src
!= srcs
.end(); ++src
) {
3647 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(*src
);
3650 afs
->done_with_peakfile_writes ();
3654 unblock_processing ();
3660 Session::gain_automation_buffer() const
3662 return ProcessThread::gain_automation_buffer ();
3666 Session::pan_automation_buffer() const
3668 return ProcessThread::pan_automation_buffer ();
3672 Session::get_silent_buffers (ChanCount count
)
3674 return ProcessThread::get_silent_buffers (count
);
3676 assert(_silent_buffers
->available() >= count
);
3677 _silent_buffers
->set_count(count
);
3679 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
3680 for (size_t i
= 0; i
< count
.get(*t
); ++i
) {
3681 _silent_buffers
->get(*t
, i
).clear();
3685 return *_silent_buffers
;
3690 Session::get_scratch_buffers (ChanCount count
)
3692 return ProcessThread::get_scratch_buffers (count
);
3694 if (count
!= ChanCount::ZERO
) {
3695 assert(_scratch_buffers
->available() >= count
);
3696 _scratch_buffers
->set_count(count
);
3698 _scratch_buffers
->set_count (_scratch_buffers
->available());
3701 return *_scratch_buffers
;
3706 Session::get_mix_buffers (ChanCount count
)
3708 return ProcessThread::get_mix_buffers (count
);
3710 assert(_mix_buffers
->available() >= count
);
3711 _mix_buffers
->set_count(count
);
3712 return *_mix_buffers
;
3717 Session::ntracks () const
3720 shared_ptr
<RouteList
> r
= routes
.reader ();
3722 for (RouteList::const_iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3723 if (boost::dynamic_pointer_cast
<Track
> (*i
)) {
3732 Session::nbusses () const
3735 shared_ptr
<RouteList
> r
= routes
.reader ();
3737 for (RouteList::const_iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3738 if (boost::dynamic_pointer_cast
<Track
>(*i
) == 0) {
3747 Session::add_automation_list(AutomationList
*al
)
3749 automation_lists
[al
->id()] = al
;
3753 Session::sync_order_keys (std::string
const & base
)
3755 if (deletion_in_progress()) {
3759 if (!Config
->get_sync_all_route_ordering()) {
3760 /* leave order keys as they are */
3764 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
3766 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3767 (*i
)->sync_order_keys (base
);
3770 Route::SyncOrderKeys (base
); // EMIT SIGNAL
3772 /* this might not do anything */
3774 set_remote_control_ids ();
3777 /** @return true if there is at least one record-enabled track, otherwise false */
3779 Session::have_rec_enabled_track () const
3781 return g_atomic_int_get (&_have_rec_enabled_track
) == 1;
3784 /** Update the state of our rec-enabled tracks flag */
3786 Session::update_have_rec_enabled_track ()
3788 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
3789 RouteList::iterator i
= rl
->begin();
3790 while (i
!= rl
->end ()) {
3792 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
3793 if (tr
&& tr
->record_enabled ()) {
3800 int const old
= g_atomic_int_get (&_have_rec_enabled_track
);
3802 g_atomic_int_set (&_have_rec_enabled_track
, i
!= rl
->end () ? 1 : 0);
3804 if (g_atomic_int_get (&_have_rec_enabled_track
) != old
) {
3805 RecordStateChanged (); /* EMIT SIGNAL */
3810 Session::listen_position_changed ()
3814 switch (Config
->get_listen_position()) {
3815 case AfterFaderListen
:
3819 case PreFaderListen
:
3824 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
3826 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3827 (*i
)->put_monitor_send_at (p
);
3832 Session::solo_control_mode_changed ()
3834 /* cancel all solo or all listen when solo control mode changes */
3837 set_solo (get_routes(), false);
3838 } else if (listening()) {
3839 set_listen (get_routes(), false);
3844 Session::route_group_changed ()
3846 RouteGroupChanged (); /* EMIT SIGNAL */
3850 Session::get_available_sync_options () const
3852 vector
<SyncSource
> ret
;
3854 ret
.push_back (JACK
);
3857 ret
.push_back (MTC
);
3860 if (midi_clock_port()) {
3861 ret
.push_back (MIDIClock
);
3867 boost::shared_ptr
<RouteList
>
3868 Session::get_routes_with_regions_at (nframes64_t
const p
) const
3870 shared_ptr
<RouteList
> r
= routes
.reader ();
3871 shared_ptr
<RouteList
> rl (new RouteList
);
3873 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
3874 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
3879 boost::shared_ptr
<Playlist
> pl
= tr
->playlist ();
3884 if (pl
->has_region_at (p
)) {
3893 Session::goto_end ()
3895 if (_session_range_location
) {
3896 request_locate (_session_range_location
->end(), false);
3898 request_locate (0, false);
3903 Session::goto_start ()
3905 if (_session_range_location
) {
3906 request_locate (_session_range_location
->start(), false);
3908 request_locate (0, false);
3913 Session::set_session_start (nframes_t start
)
3915 if (_session_range_location
) {
3916 _session_range_location
->set_start (start
);
3918 add_session_range_location (start
, start
);
3923 Session::set_session_end (nframes_t end
)
3925 if (_session_range_location
) {
3926 _session_range_location
->set_end (end
);
3928 add_session_range_location (end
, end
);
3933 Session::current_start_frame () const
3935 return _session_range_location
? _session_range_location
->start() : 0;
3939 Session::current_end_frame () const
3941 return _session_range_location
? _session_range_location
->end() : 0;
3945 Session::add_session_range_location (nframes_t start
, nframes_t end
)
3947 _session_range_location
= new Location (start
, end
, _("session"), Location::IsSessionRange
);
3948 _locations
.add (_session_range_location
);