~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/session.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 1999-2010 Paul Davis
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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.
 
17
 
 
18
*/
 
19
 
 
20
#include <stdint.h>
 
21
 
 
22
#include <algorithm>
 
23
#include <string>
 
24
#include <vector>
 
25
#include <sstream>
 
26
#include <fstream>
 
27
#include <cstdio> /* sprintf(3) ... grrr */
 
28
#include <cmath>
 
29
#include <cerrno>
 
30
#include <unistd.h>
 
31
#include <limits.h>
 
32
 
 
33
#include <glibmm/threads.h>
 
34
#include <glibmm/miscutils.h>
 
35
#include <glibmm/fileutils.h>
 
36
 
 
37
#include <boost/algorithm/string/erase.hpp>
 
38
 
 
39
#include "pbd/error.h"
 
40
#include "pbd/boost_debug.h"
 
41
#include "pbd/pathscanner.h"
 
42
#include "pbd/stl_delete.h"
 
43
#include "pbd/basename.h"
 
44
#include "pbd/stacktrace.h"
 
45
#include "pbd/file_utils.h"
 
46
#include "pbd/convert.h"
 
47
#include "pbd/strsplit.h"
 
48
#include "pbd/unwind.h"
 
49
 
 
50
#include "ardour/amp.h"
 
51
#include "ardour/analyser.h"
 
52
#include "ardour/audio_buffer.h"
 
53
#include "ardour/audio_diskstream.h"
 
54
#include "ardour/audio_port.h"
 
55
#include "ardour/audio_track.h"
 
56
#include "ardour/audioengine.h"
 
57
#include "ardour/audiofilesource.h"
 
58
#include "ardour/auditioner.h"
 
59
#include "ardour/buffer_manager.h"
 
60
#include "ardour/buffer_set.h"
 
61
#include "ardour/bundle.h"
 
62
#include "ardour/butler.h"
 
63
#include "ardour/click.h"
 
64
#include "ardour/control_protocol_manager.h"
 
65
#include "ardour/data_type.h"
 
66
#include "ardour/debug.h"
 
67
#include "ardour/filename_extensions.h"
 
68
#include "ardour/graph.h"
 
69
#include "ardour/midi_track.h"
 
70
#include "ardour/midi_ui.h"
 
71
#include "ardour/operations.h"
 
72
#include "ardour/playlist.h"
 
73
#include "ardour/plugin.h"
 
74
#include "ardour/plugin_insert.h"
 
75
#include "ardour/process_thread.h"
 
76
#include "ardour/rc_configuration.h"
 
77
#include "ardour/recent_sessions.h"
 
78
#include "ardour/region.h"
 
79
#include "ardour/region_factory.h"
 
80
#include "ardour/route_graph.h"
 
81
#include "ardour/route_group.h"
 
82
#include "ardour/send.h"
 
83
#include "ardour/session.h"
 
84
#include "ardour/session_directory.h"
 
85
#include "ardour/session_playlists.h"
 
86
#include "ardour/smf_source.h"
 
87
#include "ardour/source_factory.h"
 
88
#include "ardour/utils.h"
 
89
 
 
90
#include "midi++/port.h"
 
91
#include "midi++/jack_midi_port.h"
 
92
#include "midi++/mmc.h"
 
93
#include "midi++/manager.h"
 
94
 
 
95
#include "i18n.h"
 
96
 
 
97
namespace ARDOUR {
 
98
class MidiSource;
 
99
class Processor;
 
100
class Speakers;
 
101
}
 
102
 
 
103
using namespace std;
 
104
using namespace ARDOUR;
 
105
using namespace PBD;
 
106
 
 
107
bool Session::_disable_all_loaded_plugins = false;
 
108
 
 
109
PBD::Signal1<void,std::string> Session::Dialog;
 
110
PBD::Signal0<int> Session::AskAboutPendingState;
 
111
PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
 
112
PBD::Signal0<void> Session::SendFeedback;
 
113
PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
 
114
 
 
115
PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
 
116
PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
 
117
PBD::Signal2<void,std::string, std::string> Session::Exported;
 
118
PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
 
119
PBD::Signal0<void> Session::Quit;
 
120
PBD::Signal0<void> Session::FeedbackDetected;
 
121
PBD::Signal0<void> Session::SuccessfulGraphSort;
 
122
PBD::Signal2<void,std::string,std::string> Session::VersionMismatch;
 
123
 
 
124
static void clean_up_session_event (SessionEvent* ev) { delete ev; }
 
125
const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
 
126
 
 
127
/** @param snapshot_name Snapshot name, without .ardour suffix */
 
128
Session::Session (AudioEngine &eng,
 
129
                  const string& fullpath,
 
130
                  const string& snapshot_name,
 
131
                  BusProfile* bus_profile,
 
132
                  string mix_template)
 
133
        : _engine (eng)
 
134
        , _target_transport_speed (0.0)
 
135
        , _requested_return_frame (-1)
 
136
        , _under_nsm_control (false)
 
137
        , _session_dir (new SessionDirectory(fullpath))
 
138
        , state_tree (0)
 
139
        , _state_of_the_state (Clean)
 
140
        , _butler (new Butler (*this))
 
141
        , _post_transport_work (0)
 
142
        , _send_timecode_update (false)
 
143
        , ltc_enc_buf(0)
 
144
        , _all_route_group (new RouteGroup (*this, "all"))
 
145
        , routes (new RouteList)
 
146
        , _total_free_4k_blocks (0)
 
147
        , _total_free_4k_blocks_uncertain (false)
 
148
        , _bundles (new BundleList)
 
149
        , _bundle_xml_node (0)
 
150
        , _current_trans (0)
 
151
        , click_data (0)
 
152
        , click_emphasis_data (0)
 
153
        , main_outs (0)
 
154
        , _have_rec_enabled_track (false)
 
155
        , _suspend_timecode_transmission (0)
 
156
{
 
157
        _locations = new Locations (*this);
 
158
        ltc_encoder = NULL;
 
159
 
 
160
        if (how_many_dsp_threads () > 1) {
 
161
                /* For now, only create the graph if we are using >1 DSP threads, as
 
162
                   it is a bit slower than the old code with 1 thread.
 
163
                */
 
164
                _process_graph.reset (new Graph (*this));
 
165
        }
 
166
 
 
167
        playlists.reset (new SessionPlaylists);
 
168
 
 
169
        _all_route_group->set_active (true, this);
 
170
 
 
171
        interpolation.add_channel_to (0, 0);
 
172
 
 
173
        if (!eng.connected()) {
 
174
                throw failed_constructor();
 
175
        }
 
176
 
 
177
        n_physical_outputs = _engine.n_physical_outputs ();
 
178
        n_physical_inputs =  _engine.n_physical_inputs ();
 
179
 
 
180
        first_stage_init (fullpath, snapshot_name);
 
181
 
 
182
        _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
 
183
 
 
184
        if (_is_new) {
 
185
                if (create (mix_template, bus_profile)) {
 
186
                        destroy ();
 
187
                        throw failed_constructor ();
 
188
                }
 
189
        }
 
190
 
 
191
        if (second_stage_init ()) {
 
192
                destroy ();
 
193
                throw failed_constructor ();
 
194
        }
 
195
 
 
196
        store_recent_sessions(_name, _path);
 
197
 
 
198
        bool was_dirty = dirty();
 
199
 
 
200
        _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
 
201
 
 
202
        Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
 
203
        config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
 
204
 
 
205
        if (was_dirty) {
 
206
                DirtyChanged (); /* EMIT SIGNAL */
 
207
        }
 
208
 
 
209
        StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
 
210
        EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
 
211
 
 
212
        _is_new = false;
 
213
}
 
214
 
 
215
Session::~Session ()
 
216
{
 
217
#ifdef PT_TIMING        
 
218
        ST.dump ("ST.dump");
 
219
#endif  
 
220
        destroy ();
 
221
}
 
222
 
 
223
void
 
224
Session::destroy ()
 
225
{
 
226
        vector<void*> debug_pointers;
 
227
 
 
228
        /* if we got to here, leaving pending capture state around
 
229
           is a mistake.
 
230
        */
 
231
 
 
232
        remove_pending_capture_state ();
 
233
 
 
234
        _state_of_the_state = StateOfTheState (CannotSave|Deletion);
 
235
 
 
236
        /* disconnect from any and all signals that we are connected to */
 
237
 
 
238
        drop_connections ();
 
239
 
 
240
        _engine.remove_session ();
 
241
 
 
242
        /* deregister all ports - there will be no process or any other
 
243
         * callbacks from the engine any more.
 
244
         */
 
245
 
 
246
        Port::PortDrop (); /* EMIT SIGNAL */
 
247
 
 
248
        ltc_tx_cleanup();
 
249
 
 
250
        /* clear history so that no references to objects are held any more */
 
251
 
 
252
        _history.clear ();
 
253
 
 
254
        /* clear state tree so that no references to objects are held any more */
 
255
 
 
256
        delete state_tree;
 
257
 
 
258
        /* reset dynamic state version back to default */
 
259
 
 
260
        Stateful::loading_state_version = 0;
 
261
 
 
262
        _butler->drop_references ();
 
263
        delete _butler;
 
264
        _butler = 0;
 
265
        
 
266
        delete midi_control_ui;
 
267
        delete _all_route_group;
 
268
 
 
269
        if (click_data != default_click) {
 
270
                delete [] click_data;
 
271
        }
 
272
 
 
273
        if (click_emphasis_data != default_click_emphasis) {
 
274
                delete [] click_emphasis_data;
 
275
        }
 
276
 
 
277
        clear_clicks ();
 
278
 
 
279
        /* clear out any pending dead wood from RCU managed objects */
 
280
 
 
281
        routes.flush ();
 
282
        _bundles.flush ();
 
283
 
 
284
        AudioDiskstream::free_working_buffers();
 
285
 
 
286
        /* tell everyone who is still standing that we're about to die */
 
287
        drop_references ();
 
288
 
 
289
        /* tell everyone to drop references and delete objects as we go */
 
290
 
 
291
        DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
 
292
        RegionFactory::delete_all_regions ();
 
293
 
 
294
        DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
 
295
 
 
296
        /* reset these three references to special routes before we do the usual route delete thing */
 
297
 
 
298
        auditioner.reset ();
 
299
        _master_out.reset ();
 
300
        _monitor_out.reset ();
 
301
 
 
302
        {
 
303
                RCUWriter<RouteList> writer (routes);
 
304
                boost::shared_ptr<RouteList> r = writer.get_copy ();
 
305
 
 
306
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
307
                        DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
 
308
                        (*i)->drop_references ();
 
309
                }
 
310
 
 
311
                r->clear ();
 
312
                /* writer goes out of scope and updates master */
 
313
        }
 
314
        routes.flush ();
 
315
 
 
316
        DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
 
317
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
 
318
                DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
 
319
                i->second->drop_references ();
 
320
        }
 
321
 
 
322
        sources.clear ();
 
323
 
 
324
        DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
 
325
        for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
 
326
 
 
327
                delete *i;
 
328
        }
 
329
 
 
330
        /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
 
331
        playlists.reset ();
 
332
 
 
333
        delete _locations;
 
334
 
 
335
        DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
 
336
 
 
337
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
 
338
        boost_debug_list_ptrs ();
 
339
#endif
 
340
}
 
341
 
 
342
void
 
343
Session::when_engine_running ()
 
344
{
 
345
        string first_physical_output;
 
346
 
 
347
        BootMessage (_("Set block size and sample rate"));
 
348
 
 
349
        set_block_size (_engine.frames_per_cycle());
 
350
        set_frame_rate (_engine.frame_rate());
 
351
 
 
352
        BootMessage (_("Using configuration"));
 
353
 
 
354
        boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
 
355
        boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
 
356
 
 
357
        Config->map_parameters (ff);
 
358
        config.map_parameters (ft);
 
359
 
 
360
        /* every time we reconnect, recompute worst case output latencies */
 
361
 
 
362
        _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
 
363
 
 
364
        if (synced_to_jack()) {
 
365
                _engine.transport_stop ();
 
366
        }
 
367
 
 
368
        if (config.get_jack_time_master()) {
 
369
                _engine.transport_locate (_transport_frame);
 
370
        }
 
371
 
 
372
        _clicking = false;
 
373
 
 
374
        try {
 
375
                XMLNode* child = 0;
 
376
                
 
377
                _ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
 
378
                _ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
 
379
 
 
380
                if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
 
381
                        _ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
 
382
                } else {
 
383
                        {
 
384
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
385
                                _ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
 
386
                        }
 
387
                        reconnect_ltc_input ();
 
388
                }
 
389
 
 
390
                if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
 
391
                        _ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
 
392
                } else {
 
393
                        {
 
394
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
395
                                _ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
 
396
                        }
 
397
                        reconnect_ltc_output ();
 
398
                }
 
399
                                                
 
400
                /* fix up names of LTC ports because we don't want the normal
 
401
                 * IO style of NAME/TYPE-{in,out}N
 
402
                 */
 
403
                
 
404
                _ltc_input->nth (0)->set_name (_("LTC-in"));
 
405
                _ltc_output->nth (0)->set_name (_("LTC-out"));
 
406
 
 
407
                _click_io.reset (new ClickIO (*this, "click"));
 
408
                _click_gain.reset (new Amp (*this));
 
409
                _click_gain->activate ();
 
410
 
 
411
                if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
 
412
 
 
413
                        /* existing state for Click */
 
414
                        int c = 0;
 
415
 
 
416
                        if (Stateful::loading_state_version < 3000) {
 
417
                                c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
 
418
                        } else {
 
419
                                const XMLNodeList& children (child->children());
 
420
                                XMLNodeList::const_iterator i = children.begin();
 
421
                                if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
 
422
                                        ++i;
 
423
                                        if (i != children.end()) {
 
424
                                                c = _click_gain->set_state (**i, Stateful::loading_state_version);
 
425
                                        }
 
426
                                }
 
427
                        }
 
428
                        
 
429
                        if (c == 0) {
 
430
                                _clicking = Config->get_clicking ();
 
431
 
 
432
                        } else {
 
433
 
 
434
                                error << _("could not setup Click I/O") << endmsg;
 
435
                                _clicking = false;
 
436
                        }
 
437
 
 
438
 
 
439
                } else {
 
440
 
 
441
                        /* default state for Click: dual-mono to first 2 physical outputs */
 
442
 
 
443
                        vector<string> outs;
 
444
                        _engine.get_physical_outputs (DataType::AUDIO, outs);
 
445
 
 
446
                        for (uint32_t physport = 0; physport < 2; ++physport) {
 
447
                                if (outs.size() > physport) {
 
448
                                        if (_click_io->add_port (outs[physport], this)) {
 
449
                                                // relax, even though its an error
 
450
                                        }
 
451
                                }
 
452
                        }
 
453
 
 
454
                        if (_click_io->n_ports () > ChanCount::ZERO) {
 
455
                                _clicking = Config->get_clicking ();
 
456
                        }
 
457
                }
 
458
        }
 
459
 
 
460
        catch (failed_constructor& err) {
 
461
                error << _("cannot setup Click I/O") << endmsg;
 
462
        }
 
463
 
 
464
        BootMessage (_("Compute I/O Latencies"));
 
465
 
 
466
        if (_clicking) {
 
467
                // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
 
468
        }
 
469
 
 
470
        BootMessage (_("Set up standard connections"));
 
471
 
 
472
        vector<string> inputs[DataType::num_types];
 
473
        vector<string> outputs[DataType::num_types];
 
474
        for (uint32_t i = 0; i < DataType::num_types; ++i) {
 
475
                _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
 
476
                _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
 
477
        }
 
478
 
 
479
        /* Create a set of Bundle objects that map
 
480
           to the physical I/O currently available.  We create both
 
481
           mono and stereo bundles, so that the common cases of mono
 
482
           and stereo tracks get bundles to put in their mixer strip
 
483
           in / out menus.  There may be a nicer way of achieving that;
 
484
           it doesn't really scale that well to higher channel counts
 
485
        */
 
486
 
 
487
        /* mono output bundles */
 
488
 
 
489
        for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
 
490
                char buf[32];
 
491
                snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
 
492
 
 
493
                boost::shared_ptr<Bundle> c (new Bundle (buf, true));
 
494
                c->add_channel (_("mono"), DataType::AUDIO);
 
495
                c->set_port (0, outputs[DataType::AUDIO][np]);
 
496
 
 
497
                add_bundle (c);
 
498
        }
 
499
 
 
500
        /* stereo output bundles */
 
501
 
 
502
        for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
 
503
                if (np + 1 < outputs[DataType::AUDIO].size()) {
 
504
                        char buf[32];
 
505
                        snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
 
506
                        boost::shared_ptr<Bundle> c (new Bundle (buf, true));
 
507
                        c->add_channel (_("L"), DataType::AUDIO);
 
508
                        c->set_port (0, outputs[DataType::AUDIO][np]);
 
509
                        c->add_channel (_("R"), DataType::AUDIO);
 
510
                        c->set_port (1, outputs[DataType::AUDIO][np + 1]);
 
511
 
 
512
                        add_bundle (c);
 
513
                }
 
514
        }
 
515
 
 
516
        /* mono input bundles */
 
517
 
 
518
        for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
 
519
                char buf[32];
 
520
                snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
 
521
 
 
522
                boost::shared_ptr<Bundle> c (new Bundle (buf, false));
 
523
                c->add_channel (_("mono"), DataType::AUDIO);
 
524
                c->set_port (0, inputs[DataType::AUDIO][np]);
 
525
 
 
526
                add_bundle (c);
 
527
        }
 
528
 
 
529
        /* stereo input bundles */
 
530
 
 
531
        for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
 
532
                if (np + 1 < inputs[DataType::AUDIO].size()) {
 
533
                        char buf[32];
 
534
                        snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
 
535
 
 
536
                        boost::shared_ptr<Bundle> c (new Bundle (buf, false));
 
537
                        c->add_channel (_("L"), DataType::AUDIO);
 
538
                        c->set_port (0, inputs[DataType::AUDIO][np]);
 
539
                        c->add_channel (_("R"), DataType::AUDIO);
 
540
                        c->set_port (1, inputs[DataType::AUDIO][np + 1]);
 
541
 
 
542
                        add_bundle (c);
 
543
                }
 
544
        }
 
545
 
 
546
        /* MIDI input bundles */
 
547
 
 
548
        for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
 
549
                string n = inputs[DataType::MIDI][np];
 
550
                boost::erase_first (n, X_("alsa_pcm:"));
 
551
 
 
552
                boost::shared_ptr<Bundle> c (new Bundle (n, false));
 
553
                c->add_channel ("", DataType::MIDI);
 
554
                c->set_port (0, inputs[DataType::MIDI][np]);
 
555
                add_bundle (c);
 
556
        }
 
557
 
 
558
        /* MIDI output bundles */
 
559
 
 
560
        for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
 
561
                string n = outputs[DataType::MIDI][np];
 
562
                boost::erase_first (n, X_("alsa_pcm:"));
 
563
 
 
564
                boost::shared_ptr<Bundle> c (new Bundle (n, true));
 
565
                c->add_channel ("", DataType::MIDI);
 
566
                c->set_port (0, outputs[DataType::MIDI][np]);
 
567
                add_bundle (c);
 
568
        }
 
569
 
 
570
        BootMessage (_("Setup signal flow and plugins"));
 
571
 
 
572
        /* Reset all panners */
 
573
 
 
574
        Delivery::reset_panners ();
 
575
 
 
576
        /* this will cause the CPM to instantiate any protocols that are in use
 
577
         * (or mandatory), which will pass it this Session, and then call
 
578
         * set_state() on each instantiated protocol to match stored state.
 
579
         */
 
580
 
 
581
        ControlProtocolManager::instance().set_session (this);
 
582
 
 
583
        /* This must be done after the ControlProtocolManager set_session above,
 
584
           as it will set states for ports which the ControlProtocolManager creates.
 
585
        */
 
586
 
 
587
        MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
 
588
 
 
589
        /* And this must be done after the MIDI::Manager::set_port_states as
 
590
         * it will try to make connections whose details are loaded by set_port_states.
 
591
         */
 
592
 
 
593
        hookup_io ();
 
594
 
 
595
        /* Let control protocols know that we are now all connected, so they
 
596
         * could start talking to surfaces if they want to.
 
597
         */
 
598
 
 
599
        ControlProtocolManager::instance().midi_connectivity_established ();
 
600
 
 
601
        if (_is_new && !no_auto_connect()) {
 
602
                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
 
603
                auto_connect_master_bus ();
 
604
        }
 
605
 
 
606
        _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
 
607
 
 
608
        /* update latencies */
 
609
 
 
610
        initialize_latencies ();
 
611
 
 
612
        /* hook us up to the engine */
 
613
 
 
614
        BootMessage (_("Connect to engine"));
 
615
        _engine.set_session (this);
 
616
        _engine.reset_timebase ();
 
617
}
 
618
 
 
619
void
 
620
Session::auto_connect_master_bus ()
 
621
{
 
622
        if (!_master_out || !Config->get_auto_connect_standard_busses() || _monitor_out) {
 
623
                return;
 
624
        }
 
625
                
 
626
        /* if requested auto-connect the outputs to the first N physical ports.
 
627
         */
 
628
        
 
629
        uint32_t limit = _master_out->n_outputs().n_total();
 
630
        vector<string> outputs[DataType::num_types];
 
631
        
 
632
        for (uint32_t i = 0; i < DataType::num_types; ++i) {
 
633
                _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
 
634
        }
 
635
        
 
636
        for (uint32_t n = 0; n < limit; ++n) {
 
637
                boost::shared_ptr<Port> p = _master_out->output()->nth (n);
 
638
                string connect_to;
 
639
                if (outputs[p->type()].size() > n) {
 
640
                        connect_to = outputs[p->type()][n];
 
641
                }
 
642
                
 
643
                if (!connect_to.empty() && p->connected_to (connect_to) == false) {
 
644
                        if (_master_out->output()->connect (p, connect_to, this)) {
 
645
                                error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
 
646
                                      << endmsg;
 
647
                                break;
 
648
                        }
 
649
                }
 
650
        }
 
651
}
 
652
 
 
653
void
 
654
Session::remove_monitor_section ()
 
655
{
 
656
        if (!_monitor_out) {
 
657
                return;
 
658
        }
 
659
 
 
660
        /* force reversion to Solo-In-Place */
 
661
        Config->set_solo_control_is_listen_control (false);
 
662
 
 
663
        {
 
664
                /* Hold process lock while doing this so that we don't hear bits and
 
665
                 * pieces of audio as we work on each route.
 
666
                 */
 
667
                
 
668
                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
669
                
 
670
                /* Connect tracks to monitor section. Note that in an
 
671
                   existing session, the internal sends will already exist, but we want the
 
672
                   routes to notice that they connect to the control out specifically.
 
673
                */
 
674
                
 
675
                
 
676
                boost::shared_ptr<RouteList> r = routes.reader ();
 
677
                PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
 
678
                
 
679
                for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
 
680
                        
 
681
                        if ((*x)->is_monitor()) {
 
682
                                /* relax */
 
683
                        } else if ((*x)->is_master()) {
 
684
                                /* relax */
 
685
                        } else {
 
686
                                (*x)->remove_aux_or_listen (_monitor_out);
 
687
                        }
 
688
                }
 
689
        }
 
690
 
 
691
        remove_route (_monitor_out);
 
692
        auto_connect_master_bus ();
 
693
}
 
694
 
 
695
void
 
696
Session::add_monitor_section ()
 
697
{
 
698
        RouteList rl;
 
699
 
 
700
        if (_monitor_out || !_master_out) {
 
701
                return;
 
702
        }
 
703
 
 
704
        boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
 
705
 
 
706
        if (r->init ()) {
 
707
                return;
 
708
        }
 
709
 
 
710
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
 
711
        // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
 
712
#endif
 
713
        {
 
714
                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
715
                r->input()->ensure_io (_master_out->output()->n_ports(), false, this);
 
716
                r->output()->ensure_io (_master_out->output()->n_ports(), false, this);
 
717
        }
 
718
 
 
719
        rl.push_back (r);
 
720
        add_routes (rl, false, false, false);
 
721
        
 
722
        assert (_monitor_out);
 
723
 
 
724
        /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
 
725
           are undefined, at best.
 
726
        */
 
727
        
 
728
        uint32_t limit = _monitor_out->n_inputs().n_audio();
 
729
        
 
730
        if (_master_out) {
 
731
                
 
732
                /* connect the inputs to the master bus outputs. this
 
733
                 * represents a separate data feed from the internal sends from
 
734
                 * each route. as of jan 2011, it allows the monitor section to
 
735
                 * conditionally ignore either the internal sends or the normal
 
736
                 * input feed, but we should really find a better way to do
 
737
                 * this, i think.
 
738
                 */
 
739
 
 
740
                _master_out->output()->disconnect (this);
 
741
 
 
742
                for (uint32_t n = 0; n < limit; ++n) {
 
743
                        boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n);
 
744
                        boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n);
 
745
                        
 
746
                        if (o) {
 
747
                                string connect_to = o->name();
 
748
                                if (_monitor_out->input()->connect (p, connect_to, this)) {
 
749
                                        error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
 
750
                                              << endmsg;
 
751
                                        break;
 
752
                                }
 
753
                        }
 
754
                }
 
755
        }
 
756
        
 
757
        /* if monitor section is not connected, connect it to physical outs
 
758
         */
 
759
        
 
760
        if (Config->get_auto_connect_standard_busses() && !_monitor_out->output()->connected ()) {
 
761
                
 
762
                if (!Config->get_monitor_bus_preferred_bundle().empty()) {
 
763
                        
 
764
                        boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
 
765
                        
 
766
                        if (b) {
 
767
                                _monitor_out->output()->connect_ports_to_bundle (b, true, this);
 
768
                        } else {
 
769
                                warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
 
770
                                                           Config->get_monitor_bus_preferred_bundle())
 
771
                                        << endmsg;
 
772
                        }
 
773
                        
 
774
                } else {
 
775
                        
 
776
                        /* Monitor bus is audio only */
 
777
 
 
778
                        uint32_t mod = n_physical_outputs.get (DataType::AUDIO);
 
779
                        uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
 
780
                        vector<string> outputs[DataType::num_types];
 
781
 
 
782
                        for (uint32_t i = 0; i < DataType::num_types; ++i) {
 
783
                                _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
 
784
                        }
 
785
                        
 
786
                        
 
787
                        if (mod != 0) {
 
788
                                
 
789
                                for (uint32_t n = 0; n < limit; ++n) {
 
790
                                        
 
791
                                        boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
 
792
                                        string connect_to;
 
793
                                        if (outputs[DataType::AUDIO].size() > (n % mod)) {
 
794
                                                connect_to = outputs[DataType::AUDIO][n % mod];
 
795
                                        }
 
796
                                        
 
797
                                        if (!connect_to.empty()) {
 
798
                                                if (_monitor_out->output()->connect (p, connect_to, this)) {
 
799
                                                        error << string_compose (
 
800
                                                                _("cannot connect control output %1 to %2"),
 
801
                                                                n, connect_to)
 
802
                                                              << endmsg;
 
803
                                                        break;
 
804
                                                }
 
805
                                        }
 
806
                                }
 
807
                        }
 
808
                }
 
809
        }
 
810
 
 
811
        /* Hold process lock while doing this so that we don't hear bits and
 
812
         * pieces of audio as we work on each route.
 
813
         */
 
814
         
 
815
        Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
816
 
 
817
        /* Connect tracks to monitor section. Note that in an
 
818
           existing session, the internal sends will already exist, but we want the
 
819
           routes to notice that they connect to the control out specifically.
 
820
        */
 
821
 
 
822
 
 
823
        boost::shared_ptr<RouteList> rls = routes.reader ();
 
824
 
 
825
        PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
 
826
 
 
827
        for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) {
 
828
                
 
829
                if ((*x)->is_monitor()) {
 
830
                        /* relax */
 
831
                } else if ((*x)->is_master()) {
 
832
                        /* relax */
 
833
                } else {
 
834
                        (*x)->enable_monitor_send ();
 
835
                }
 
836
        }
 
837
}
 
838
 
 
839
void
 
840
Session::hookup_io ()
 
841
{
 
842
        /* stop graph reordering notifications from
 
843
           causing resorts, etc.
 
844
        */
 
845
 
 
846
        _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
 
847
 
 
848
        if (!auditioner) {
 
849
 
 
850
                /* we delay creating the auditioner till now because
 
851
                   it makes its own connections to ports.
 
852
                */
 
853
 
 
854
                try {
 
855
                        boost::shared_ptr<Auditioner> a (new Auditioner (*this));
 
856
                        if (a->init()) {
 
857
                                throw failed_constructor ();
 
858
                        }
 
859
                        a->use_new_diskstream ();
 
860
                        auditioner = a;
 
861
                }
 
862
 
 
863
                catch (failed_constructor& err) {
 
864
                        warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
 
865
                }
 
866
        }
 
867
 
 
868
        /* load bundles, which we may have postponed earlier on */
 
869
        if (_bundle_xml_node) {
 
870
                load_bundles (*_bundle_xml_node);
 
871
                delete _bundle_xml_node;
 
872
        }
 
873
 
 
874
        /* Tell all IO objects to connect themselves together */
 
875
 
 
876
        IO::enable_connecting ();
 
877
        MIDI::JackMIDIPort::MakeConnections ();
 
878
 
 
879
        /* Anyone who cares about input state, wake up and do something */
 
880
 
 
881
        IOConnectionsComplete (); /* EMIT SIGNAL */
 
882
 
 
883
        _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
 
884
 
 
885
        /* now handle the whole enchilada as if it was one
 
886
           graph reorder event.
 
887
        */
 
888
 
 
889
        graph_reordered ();
 
890
 
 
891
        /* update the full solo state, which can't be
 
892
           correctly determined on a per-route basis, but
 
893
           needs the global overview that only the session
 
894
           has.
 
895
        */
 
896
 
 
897
        update_route_solo_state ();
 
898
}
 
899
 
 
900
void
 
901
Session::track_playlist_changed (boost::weak_ptr<Track> wp)
 
902
{
 
903
        boost::shared_ptr<Track> track = wp.lock ();
 
904
        if (!track) {
 
905
                return;
 
906
        }
 
907
 
 
908
        boost::shared_ptr<Playlist> playlist;
 
909
 
 
910
        if ((playlist = track->playlist()) != 0) {
 
911
                playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
 
912
                playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
 
913
                playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
 
914
        }
 
915
}
 
916
 
 
917
bool
 
918
Session::record_enabling_legal () const
 
919
{
 
920
        /* this used to be in here, but survey says.... we don't need to restrict it */
 
921
        // if (record_status() == Recording) {
 
922
        //      return false;
 
923
        // }
 
924
 
 
925
        if (Config->get_all_safe()) {
 
926
                return false;
 
927
        }
 
928
        return true;
 
929
}
 
930
 
 
931
void
 
932
Session::set_track_monitor_input_status (bool yn)
 
933
{
 
934
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
935
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
936
                boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
 
937
                if (tr && tr->record_enabled ()) {
 
938
                        //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
 
939
                        tr->request_jack_monitors_input (yn);
 
940
                }
 
941
        }
 
942
}
 
943
 
 
944
void
 
945
Session::auto_punch_start_changed (Location* location)
 
946
{
 
947
        replace_event (SessionEvent::PunchIn, location->start());
 
948
 
 
949
        if (get_record_enabled() && config.get_punch_in()) {
 
950
                /* capture start has been changed, so save new pending state */
 
951
                save_state ("", true);
 
952
        }
 
953
}
 
954
 
 
955
void
 
956
Session::auto_punch_end_changed (Location* location)
 
957
{
 
958
        framepos_t when_to_stop = location->end();
 
959
        // when_to_stop += _worst_output_latency + _worst_input_latency;
 
960
        replace_event (SessionEvent::PunchOut, when_to_stop);
 
961
}
 
962
 
 
963
void
 
964
Session::auto_punch_changed (Location* location)
 
965
{
 
966
        framepos_t when_to_stop = location->end();
 
967
 
 
968
        replace_event (SessionEvent::PunchIn, location->start());
 
969
        //when_to_stop += _worst_output_latency + _worst_input_latency;
 
970
        replace_event (SessionEvent::PunchOut, when_to_stop);
 
971
}
 
972
 
 
973
/** @param loc A loop location.
 
974
 *  @param pos Filled in with the start time of the required fade-out (in session frames).
 
975
 *  @param length Filled in with the length of the required fade-out.
 
976
 */
 
977
void
 
978
Session::auto_loop_declick_range (Location* loc, framepos_t & pos, framepos_t & length)
 
979
{
 
980
        pos = max (loc->start(), loc->end() - 64);
 
981
        length = loc->end() - pos;
 
982
}
 
983
 
 
984
void
 
985
Session::auto_loop_changed (Location* location)
 
986
{
 
987
        replace_event (SessionEvent::AutoLoop, location->end(), location->start());
 
988
        framepos_t dcp;
 
989
        framecnt_t dcl;
 
990
        auto_loop_declick_range (location, dcp, dcl);
 
991
        replace_event (SessionEvent::AutoLoopDeclick, dcp, dcl);
 
992
 
 
993
        if (transport_rolling() && play_loop) {
 
994
 
 
995
 
 
996
                // if (_transport_frame > location->end()) {
 
997
 
 
998
                if (_transport_frame < location->start() || _transport_frame > location->end()) {
 
999
                        // relocate to beginning of loop
 
1000
                        clear_events (SessionEvent::LocateRoll);
 
1001
 
 
1002
                        request_locate (location->start(), true);
 
1003
 
 
1004
                }
 
1005
                else if (Config->get_seamless_loop() && !loop_changing) {
 
1006
 
 
1007
                        // schedule a locate-roll to refill the diskstreams at the
 
1008
                        // previous loop end
 
1009
                        loop_changing = true;
 
1010
 
 
1011
                        if (location->end() > last_loopend) {
 
1012
                                clear_events (SessionEvent::LocateRoll);
 
1013
                                SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
 
1014
                                queue_event (ev);
 
1015
                        }
 
1016
 
 
1017
                }
 
1018
        }
 
1019
 
 
1020
        last_loopend = location->end();
 
1021
}
 
1022
 
 
1023
void
 
1024
Session::set_auto_punch_location (Location* location)
 
1025
{
 
1026
        Location* existing;
 
1027
 
 
1028
        if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
 
1029
                punch_connections.drop_connections();
 
1030
                existing->set_auto_punch (false, this);
 
1031
                remove_event (existing->start(), SessionEvent::PunchIn);
 
1032
                clear_events (SessionEvent::PunchOut);
 
1033
                auto_punch_location_changed (0);
 
1034
        }
 
1035
 
 
1036
        set_dirty();
 
1037
 
 
1038
        if (location == 0) {
 
1039
                return;
 
1040
        }
 
1041
 
 
1042
        if (location->end() <= location->start()) {
 
1043
                error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
 
1044
                return;
 
1045
        }
 
1046
 
 
1047
        punch_connections.drop_connections ();
 
1048
 
 
1049
        location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
 
1050
        location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
 
1051
        location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
 
1052
 
 
1053
        location->set_auto_punch (true, this);
 
1054
 
 
1055
        auto_punch_changed (location);
 
1056
 
 
1057
        auto_punch_location_changed (location);
 
1058
}
 
1059
 
 
1060
void
 
1061
Session::set_auto_loop_location (Location* location)
 
1062
{
 
1063
        Location* existing;
 
1064
 
 
1065
        if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
 
1066
                loop_connections.drop_connections ();
 
1067
                existing->set_auto_loop (false, this);
 
1068
                remove_event (existing->end(), SessionEvent::AutoLoop);
 
1069
                framepos_t dcp;
 
1070
                framecnt_t dcl;
 
1071
                auto_loop_declick_range (existing, dcp, dcl);
 
1072
                remove_event (dcp, SessionEvent::AutoLoopDeclick);
 
1073
                auto_loop_location_changed (0);
 
1074
        }
 
1075
 
 
1076
        set_dirty();
 
1077
 
 
1078
        if (location == 0) {
 
1079
                return;
 
1080
        }
 
1081
 
 
1082
        if (location->end() <= location->start()) {
 
1083
                error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg;
 
1084
                return;
 
1085
        }
 
1086
 
 
1087
        last_loopend = location->end();
 
1088
 
 
1089
        loop_connections.drop_connections ();
 
1090
 
 
1091
        location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
 
1092
        location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
 
1093
        location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
 
1094
 
 
1095
        location->set_auto_loop (true, this);
 
1096
 
 
1097
        /* take care of our stuff first */
 
1098
 
 
1099
        auto_loop_changed (location);
 
1100
 
 
1101
        /* now tell everyone else */
 
1102
 
 
1103
        auto_loop_location_changed (location);
 
1104
}
 
1105
 
 
1106
void
 
1107
Session::locations_added (Location *)
 
1108
{
 
1109
        set_dirty ();
 
1110
}
 
1111
 
 
1112
void
 
1113
Session::locations_changed ()
 
1114
{
 
1115
        _locations->apply (*this, &Session::handle_locations_changed);
 
1116
}
 
1117
 
 
1118
void
 
1119
Session::handle_locations_changed (Locations::LocationList& locations)
 
1120
{
 
1121
        Locations::LocationList::iterator i;
 
1122
        Location* location;
 
1123
        bool set_loop = false;
 
1124
        bool set_punch = false;
 
1125
 
 
1126
        for (i = locations.begin(); i != locations.end(); ++i) {
 
1127
 
 
1128
                location =* i;
 
1129
 
 
1130
                if (location->is_auto_punch()) {
 
1131
                        set_auto_punch_location (location);
 
1132
                        set_punch = true;
 
1133
                }
 
1134
                if (location->is_auto_loop()) {
 
1135
                        set_auto_loop_location (location);
 
1136
                        set_loop = true;
 
1137
                }
 
1138
 
 
1139
                if (location->is_session_range()) {
 
1140
                        _session_range_location = location;
 
1141
                }
 
1142
        }
 
1143
 
 
1144
        if (!set_loop) {
 
1145
                set_auto_loop_location (0);
 
1146
        }
 
1147
        if (!set_punch) {
 
1148
                set_auto_punch_location (0);
 
1149
        }
 
1150
 
 
1151
        set_dirty();
 
1152
}
 
1153
 
 
1154
void
 
1155
Session::enable_record ()
 
1156
{
 
1157
        if (_transport_speed != 0.0 && _transport_speed != 1.0) {
 
1158
                /* no recording at anything except normal speed */
 
1159
                return;
 
1160
        }
 
1161
 
 
1162
        while (1) {
 
1163
                RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
 
1164
 
 
1165
                if (rs == Recording) {
 
1166
                        break;
 
1167
                }
 
1168
                
 
1169
                if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
 
1170
 
 
1171
                        _last_record_location = _transport_frame;
 
1172
                        MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
 
1173
 
 
1174
                        if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
 
1175
                                set_track_monitor_input_status (true);
 
1176
                        }
 
1177
 
 
1178
                        RecordStateChanged ();
 
1179
                        break;
 
1180
                }
 
1181
        }
 
1182
}
 
1183
 
 
1184
void
 
1185
Session::disable_record (bool rt_context, bool force)
 
1186
{
 
1187
        RecordState rs;
 
1188
 
 
1189
        if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
 
1190
 
 
1191
                if ((!Config->get_latched_record_enable () && !play_loop) || force) {
 
1192
                        g_atomic_int_set (&_record_status, Disabled);
 
1193
                        MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
 
1194
                } else {
 
1195
                        if (rs == Recording) {
 
1196
                                g_atomic_int_set (&_record_status, Enabled);
 
1197
                        }
 
1198
                }
 
1199
 
 
1200
                if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
 
1201
                        set_track_monitor_input_status (false);
 
1202
                }
 
1203
 
 
1204
                RecordStateChanged (); /* emit signal */
 
1205
 
 
1206
                if (!rt_context) {
 
1207
                        remove_pending_capture_state ();
 
1208
                }
 
1209
        }
 
1210
}
 
1211
 
 
1212
void
 
1213
Session::step_back_from_record ()
 
1214
{
 
1215
        if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
 
1216
 
 
1217
                if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
 
1218
                        set_track_monitor_input_status (false);
 
1219
                }
 
1220
 
 
1221
                RecordStateChanged (); /* emit signal */
 
1222
        }
 
1223
}
 
1224
 
 
1225
void
 
1226
Session::maybe_enable_record ()
 
1227
{
 
1228
        if (_step_editors > 0) {
 
1229
                return;
 
1230
        }
 
1231
 
 
1232
        g_atomic_int_set (&_record_status, Enabled);
 
1233
 
 
1234
        /* This function is currently called from somewhere other than an RT thread.
 
1235
           This save_state() call therefore doesn't impact anything.  Doing it here
 
1236
           means that we save pending state of which sources the next record will use,
 
1237
           which gives us some chance of recovering from a crash during the record.
 
1238
        */
 
1239
 
 
1240
        save_state ("", true);
 
1241
 
 
1242
        if (_transport_speed) {
 
1243
                if (!config.get_punch_in()) {
 
1244
                        enable_record ();
 
1245
                }
 
1246
        } else {
 
1247
                MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
 
1248
                RecordStateChanged (); /* EMIT SIGNAL */
 
1249
        }
 
1250
 
 
1251
        set_dirty();
 
1252
}
 
1253
 
 
1254
framepos_t
 
1255
Session::audible_frame () const
 
1256
{
 
1257
        framepos_t ret;
 
1258
        framepos_t tf;
 
1259
        framecnt_t offset;
 
1260
 
 
1261
        /* the first of these two possible settings for "offset"
 
1262
           mean that the audible frame is stationary until
 
1263
           audio emerges from the latency compensation
 
1264
           "pseudo-pipeline".
 
1265
 
 
1266
           the second means that the audible frame is stationary
 
1267
           until audio would emerge from a physical port
 
1268
           in the absence of any plugin latency compensation
 
1269
        */
 
1270
 
 
1271
        offset = worst_playback_latency ();
 
1272
 
 
1273
        if (offset > current_block_size) {
 
1274
                offset -= current_block_size;
 
1275
        } else {
 
1276
                /* XXX is this correct? if we have no external
 
1277
                   physical connections and everything is internal
 
1278
                   then surely this is zero? still, how
 
1279
                   likely is that anyway?
 
1280
                */
 
1281
                offset = current_block_size;
 
1282
        }
 
1283
 
 
1284
        if (synced_to_jack()) {
 
1285
                tf = _engine.transport_frame();
 
1286
        } else {
 
1287
                tf = _transport_frame;
 
1288
        }
 
1289
 
 
1290
        ret = tf;
 
1291
 
 
1292
        if (!non_realtime_work_pending()) {
 
1293
 
 
1294
                /* MOVING */
 
1295
 
 
1296
                /* Check to see if we have passed the first guaranteed
 
1297
                   audible frame past our last start position. if not,
 
1298
                   return that last start point because in terms
 
1299
                   of audible frames, we have not moved yet.
 
1300
 
 
1301
                   `Start position' in this context means the time we last
 
1302
                   either started, located, or changed transport direction.
 
1303
                */
 
1304
 
 
1305
                if (_transport_speed > 0.0f) {
 
1306
 
 
1307
                        if (!play_loop || !have_looped) {
 
1308
                                if (tf < _last_roll_or_reversal_location + offset) {
 
1309
                                        return _last_roll_or_reversal_location;
 
1310
                                }
 
1311
                        }
 
1312
 
 
1313
 
 
1314
                        /* forwards */
 
1315
                        ret -= offset;
 
1316
 
 
1317
                } else if (_transport_speed < 0.0f) {
 
1318
 
 
1319
                        /* XXX wot? no backward looping? */
 
1320
 
 
1321
                        if (tf > _last_roll_or_reversal_location - offset) {
 
1322
                                return _last_roll_or_reversal_location;
 
1323
                        } else {
 
1324
                                /* backwards */
 
1325
                                ret += offset;
 
1326
                        }
 
1327
                }
 
1328
        }
 
1329
 
 
1330
        return ret;
 
1331
}
 
1332
 
 
1333
void
 
1334
Session::set_frame_rate (framecnt_t frames_per_second)
 
1335
{
 
1336
        /** \fn void Session::set_frame_size(framecnt_t)
 
1337
                the AudioEngine object that calls this guarantees
 
1338
                that it will not be called while we are also in
 
1339
                ::process(). Its fine to do things that block
 
1340
                here.
 
1341
        */
 
1342
 
 
1343
        _base_frame_rate = frames_per_second;
 
1344
 
 
1345
        sync_time_vars();
 
1346
 
 
1347
        clear_clicks ();
 
1348
 
 
1349
        // XXX we need some equivalent to this, somehow
 
1350
        // SndFileSource::setup_standard_crossfades (frames_per_second);
 
1351
 
 
1352
        set_dirty();
 
1353
 
 
1354
        /* XXX need to reset/reinstantiate all LADSPA plugins */
 
1355
}
 
1356
 
 
1357
void
 
1358
Session::set_block_size (pframes_t nframes)
 
1359
{
 
1360
        /* the AudioEngine guarantees
 
1361
           that it will not be called while we are also in
 
1362
           ::process(). It is therefore fine to do things that block
 
1363
           here.
 
1364
        */
 
1365
        
 
1366
        {
 
1367
                current_block_size = nframes;
 
1368
 
 
1369
                ensure_buffers ();
 
1370
 
 
1371
                boost::shared_ptr<RouteList> r = routes.reader ();
 
1372
 
 
1373
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
1374
                        (*i)->set_block_size (nframes);
 
1375
                }
 
1376
 
 
1377
                boost::shared_ptr<RouteList> rl = routes.reader ();
 
1378
                for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
1379
                        boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
1380
                        if (tr) {
 
1381
                                tr->set_block_size (nframes);
 
1382
                        }
 
1383
                }
 
1384
 
 
1385
                set_worst_io_latencies ();
 
1386
        }
 
1387
}
 
1388
 
 
1389
 
 
1390
static void
 
1391
trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
 
1392
{
 
1393
        boost::shared_ptr<Route> r2;
 
1394
 
 
1395
        if (r1->feeds (rbase) && rbase->feeds (r1)) {
 
1396
                info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
 
1397
                return;
 
1398
        }
 
1399
 
 
1400
        /* make a copy of the existing list of routes that feed r1 */
 
1401
 
 
1402
        Route::FedBy existing (r1->fed_by());
 
1403
 
 
1404
        /* for each route that feeds r1, recurse, marking it as feeding
 
1405
           rbase as well.
 
1406
        */
 
1407
 
 
1408
        for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
 
1409
                if (!(r2 = i->r.lock ())) {
 
1410
                        /* (*i) went away, ignore it */
 
1411
                        continue;
 
1412
                }
 
1413
 
 
1414
                /* r2 is a route that feeds r1 which somehow feeds base. mark
 
1415
                   base as being fed by r2
 
1416
                */
 
1417
 
 
1418
                rbase->add_fed_by (r2, i->sends_only);
 
1419
 
 
1420
                if (r2 != rbase) {
 
1421
 
 
1422
                        /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
 
1423
                           stop here.
 
1424
                        */
 
1425
 
 
1426
                        if (r1->feeds (r2) && r2->feeds (r1)) {
 
1427
                                continue;
 
1428
                        }
 
1429
 
 
1430
                        /* now recurse, so that we can mark base as being fed by
 
1431
                           all routes that feed r2
 
1432
                        */
 
1433
 
 
1434
                        trace_terminal (r2, rbase);
 
1435
                }
 
1436
 
 
1437
        }
 
1438
}
 
1439
 
 
1440
void
 
1441
Session::resort_routes ()
 
1442
{
 
1443
        /* don't do anything here with signals emitted
 
1444
           by Routes during initial setup or while we
 
1445
           are being destroyed.
 
1446
        */
 
1447
 
 
1448
        if (_state_of_the_state & (InitialConnecting | Deletion)) {
 
1449
                return;
 
1450
        }
 
1451
 
 
1452
        {
 
1453
                RCUWriter<RouteList> writer (routes);
 
1454
                boost::shared_ptr<RouteList> r = writer.get_copy ();
 
1455
                resort_routes_using (r);
 
1456
                /* writer goes out of scope and forces update */
 
1457
        }
 
1458
 
 
1459
#ifndef NDEBUG
 
1460
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
1461
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
1462
                DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
 
1463
 
 
1464
                const Route::FedBy& fb ((*i)->fed_by());
 
1465
 
 
1466
                for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
 
1467
                        boost::shared_ptr<Route> sf = f->r.lock();
 
1468
                        if (sf) {
 
1469
                                DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
 
1470
                        }
 
1471
                }
 
1472
        }
 
1473
#endif
 
1474
 
 
1475
}
 
1476
 
 
1477
/** This is called whenever we need to rebuild the graph of how we will process
 
1478
 *  routes.
 
1479
 *  @param r List of routes, in any order.
 
1480
 */
 
1481
 
 
1482
void
 
1483
Session::resort_routes_using (boost::shared_ptr<RouteList> r)
 
1484
{
 
1485
        /* We are going to build a directed graph of our routes;
 
1486
           this is where the edges of that graph are put.
 
1487
        */
 
1488
        
 
1489
        GraphEdges edges;
 
1490
 
 
1491
        /* Go through all routes doing two things:
 
1492
         *
 
1493
         * 1. Collect the edges of the route graph.  Each of these edges
 
1494
         *    is a pair of routes, one of which directly feeds the other
 
1495
         *    either by a JACK connection or by an internal send.
 
1496
         *
 
1497
         * 2. Begin the process of making routes aware of which other
 
1498
         *    routes directly or indirectly feed them.  This information
 
1499
         *    is used by the solo code.
 
1500
         */
 
1501
           
 
1502
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
1503
 
 
1504
                /* Clear out the route's list of direct or indirect feeds */
 
1505
                (*i)->clear_fed_by ();
 
1506
 
 
1507
                for (RouteList::iterator j = r->begin(); j != r->end(); ++j) {
 
1508
 
 
1509
                        bool via_sends_only;
 
1510
 
 
1511
                        /* See if this *j feeds *i according to the current state of the JACK
 
1512
                           connections and internal sends.
 
1513
                        */
 
1514
                        if ((*j)->direct_feeds_according_to_reality (*i, &via_sends_only)) {
 
1515
                                /* add the edge to the graph (part #1) */
 
1516
                                edges.add (*j, *i, via_sends_only);
 
1517
                                /* tell the route (for part #2) */
 
1518
                                (*i)->add_fed_by (*j, via_sends_only);
 
1519
                        }
 
1520
                }
 
1521
        }
 
1522
 
 
1523
        /* Attempt a topological sort of the route graph */
 
1524
        boost::shared_ptr<RouteList> sorted_routes = topological_sort (r, edges);
 
1525
        
 
1526
        if (sorted_routes) {
 
1527
                /* We got a satisfactory topological sort, so there is no feedback;
 
1528
                   use this new graph.
 
1529
 
 
1530
                   Note: the process graph rechain does not require a
 
1531
                   topologically-sorted list, but hey ho.
 
1532
                */
 
1533
                if (_process_graph) {
 
1534
                        _process_graph->rechain (sorted_routes, edges);
 
1535
                }
 
1536
                
 
1537
                _current_route_graph = edges;
 
1538
 
 
1539
                /* Complete the building of the routes' lists of what directly
 
1540
                   or indirectly feeds them.
 
1541
                */
 
1542
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
1543
                        trace_terminal (*i, *i);
 
1544
                }
 
1545
 
 
1546
                *r = *sorted_routes;
 
1547
 
 
1548
#ifndef NDEBUG
 
1549
                DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
 
1550
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
1551
                        DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
 
1552
                                                                   (*i)->name(), (*i)->order_key (MixerSort)));
 
1553
                }
 
1554
#endif
 
1555
 
 
1556
                SuccessfulGraphSort (); /* EMIT SIGNAL */
 
1557
 
 
1558
        } else {
 
1559
                /* The topological sort failed, so we have a problem.  Tell everyone
 
1560
                   and stick to the old graph; this will continue to be processed, so
 
1561
                   until the feedback is fixed, what is played back will not quite
 
1562
                   reflect what is actually connected.  Note also that we do not
 
1563
                   do trace_terminal here, as it would fail due to an endless recursion,
 
1564
                   so the solo code will think that everything is still connected
 
1565
                   as it was before.
 
1566
                */
 
1567
                
 
1568
                FeedbackDetected (); /* EMIT SIGNAL */
 
1569
        }
 
1570
 
 
1571
}
 
1572
 
 
1573
/** Find a route name starting with \a base, maybe followed by the
 
1574
 *  lowest \a id.  \a id will always be added if \a definitely_add_number
 
1575
 *  is true on entry; otherwise it will only be added if required
 
1576
 *  to make the name unique.
 
1577
 *
 
1578
 *  Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
 
1579
 *  The available route name with the lowest ID will be used, and \a id
 
1580
 *  will be set to the ID.
 
1581
 *
 
1582
 *  \return false if a route name could not be found, and \a track_name
 
1583
 *  and \a id do not reflect a free route name.
 
1584
 */
 
1585
bool
 
1586
Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
 
1587
{
 
1588
        if (!definitely_add_number && route_by_name (base) == 0) {
 
1589
                /* juse use the base */
 
1590
                snprintf (name, name_len, "%s", base.c_str());
 
1591
                return true;
 
1592
        }
 
1593
 
 
1594
        do {
 
1595
                snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
 
1596
 
 
1597
                if (route_by_name (name) == 0) {
 
1598
                        return true;
 
1599
                }
 
1600
 
 
1601
                ++id;
 
1602
                
 
1603
        } while (id < (UINT_MAX-1));
 
1604
 
 
1605
        return false;
 
1606
}
 
1607
 
 
1608
/** Count the total ins and outs of all non-hidden tracks in the session and return them in in and out */
 
1609
void
 
1610
Session::count_existing_track_channels (ChanCount& in, ChanCount& out)
 
1611
{
 
1612
        in  = ChanCount::ZERO;
 
1613
        out = ChanCount::ZERO;
 
1614
 
 
1615
        boost::shared_ptr<RouteList> r = routes.reader ();
 
1616
 
 
1617
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
1618
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
1619
                if (tr && !tr->is_auditioner()) {
 
1620
                        in  += tr->n_inputs();
 
1621
                        out += tr->n_outputs();
 
1622
                }
 
1623
        }
 
1624
}
 
1625
 
 
1626
/** Caller must not hold process lock
 
1627
 *  @param name_template string to use for the start of the name, or "" to use "MIDI".
 
1628
 *  @param instrument plugin info for the instrument to insert pre-fader, if any
 
1629
 */
 
1630
list<boost::shared_ptr<MidiTrack> >
 
1631
Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument, 
 
1632
                         TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
 
1633
{
 
1634
        char track_name[32];
 
1635
        uint32_t track_id = 0;
 
1636
        string port;
 
1637
        RouteList new_routes;
 
1638
        list<boost::shared_ptr<MidiTrack> > ret;
 
1639
 
 
1640
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
 
1641
 
 
1642
        while (how_many) {
 
1643
                if (!find_route_name (name_template.empty() ? _("MIDI") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
 
1644
                        error << "cannot find name for new midi track" << endmsg;
 
1645
                        goto failed;
 
1646
                }
 
1647
 
 
1648
                boost::shared_ptr<MidiTrack> track;
 
1649
 
 
1650
                try {
 
1651
                        track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
 
1652
 
 
1653
                        if (track->init ()) {
 
1654
                                goto failed;
 
1655
                        }
 
1656
 
 
1657
                        track->use_new_diskstream();
 
1658
 
 
1659
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
 
1660
                        // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
 
1661
#endif
 
1662
                        {
 
1663
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
1664
                                if (track->input()->ensure_io (input, false, this)) {
 
1665
                                        error << "cannot configure " << input << " out configuration for new midi track" << endmsg;     
 
1666
                                        goto failed;
 
1667
                                }
 
1668
 
 
1669
                                if (track->output()->ensure_io (output, false, this)) {
 
1670
                                        error << "cannot configure " << output << " out configuration for new midi track" << endmsg;
 
1671
                                        goto failed;
 
1672
                                }
 
1673
                        }
 
1674
 
 
1675
                        track->non_realtime_input_change();
 
1676
 
 
1677
                        if (route_group) {
 
1678
                                route_group->add (track);
 
1679
                        }
 
1680
 
 
1681
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
 
1682
 
 
1683
                        if (Config->get_remote_model() == UserOrdered) {
 
1684
                                track->set_remote_control_id (next_control_id());
 
1685
                        }
 
1686
 
 
1687
                        new_routes.push_back (track);
 
1688
                        ret.push_back (track);
 
1689
                }
 
1690
 
 
1691
                catch (failed_constructor &err) {
 
1692
                        error << _("Session: could not create new midi track.") << endmsg;
 
1693
                        goto failed;
 
1694
                }
 
1695
 
 
1696
                catch (AudioEngine::PortRegistrationFailure& pfe) {
 
1697
 
 
1698
                        error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
 
1699
                        goto failed;
 
1700
                }
 
1701
 
 
1702
                --how_many;
 
1703
        }
 
1704
 
 
1705
  failed:
 
1706
        if (!new_routes.empty()) {
 
1707
                add_routes (new_routes, true, true, true);
 
1708
 
 
1709
                if (instrument) {
 
1710
                        for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) {
 
1711
                                PluginPtr plugin = instrument->load (*this);
 
1712
                                boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
 
1713
                                (*r)->add_processor (p, PreFader);
 
1714
                                
 
1715
                        }
 
1716
                }
 
1717
        }
 
1718
 
 
1719
        return ret;
 
1720
}
 
1721
 
 
1722
void
 
1723
Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
 
1724
{
 
1725
        boost::shared_ptr<Route> midi_track (wmt.lock());
 
1726
 
 
1727
        if (!midi_track) {
 
1728
                return;
 
1729
        }
 
1730
 
 
1731
        if ((change.type & IOChange::ConfigurationChanged) && Config->get_output_auto_connect() != ManualConnect) {
 
1732
 
 
1733
                if (change.after.n_audio() <= change.before.n_audio()) {
 
1734
                        return;
 
1735
                }
 
1736
 
 
1737
                /* new audio ports: make sure the audio goes somewhere useful,
 
1738
                   unless the user has no-auto-connect selected.
 
1739
 
 
1740
                   The existing ChanCounts don't matter for this call as they are only
 
1741
                   to do with matching input and output indices, and we are only changing
 
1742
                   outputs here.
 
1743
                */
 
1744
 
 
1745
                ChanCount dummy;
 
1746
 
 
1747
                auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
 
1748
        }
 
1749
}
 
1750
 
 
1751
/** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
 
1752
 *  @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
 
1753
 *  @param output_start As \a input_start, but for outputs.
 
1754
 */
 
1755
void
 
1756
Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
 
1757
                             bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
 
1758
{
 
1759
        if (!IO::connecting_legal) {
 
1760
                return;
 
1761
        }
 
1762
 
 
1763
        Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
 
1764
 
 
1765
        if (with_lock) {
 
1766
                lm.acquire ();
 
1767
        }
 
1768
 
 
1769
        /* If both inputs and outputs are auto-connected to physical ports,
 
1770
           use the max of input and output offsets to ensure auto-connected
 
1771
           port numbers always match up (e.g. the first audio input and the
 
1772
           first audio output of the route will have the same physical
 
1773
           port number).  Otherwise just use the lowest input or output
 
1774
           offset possible.
 
1775
        */
 
1776
 
 
1777
        DEBUG_TRACE (DEBUG::Graph,
 
1778
                     string_compose("Auto-connect: existing in = %1 out = %2\n",
 
1779
                                    existing_inputs, existing_outputs));
 
1780
 
 
1781
        const bool in_out_physical =
 
1782
                (Config->get_input_auto_connect() & AutoConnectPhysical)
 
1783
                && (Config->get_output_auto_connect() & AutoConnectPhysical)
 
1784
                && connect_inputs;
 
1785
 
 
1786
        const ChanCount in_offset = in_out_physical
 
1787
                ? ChanCount::max(existing_inputs, existing_outputs)
 
1788
                : existing_inputs;
 
1789
 
 
1790
        const ChanCount out_offset = in_out_physical
 
1791
                ? ChanCount::max(existing_inputs, existing_outputs)
 
1792
                : existing_outputs;
 
1793
 
 
1794
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
1795
                vector<string> physinputs;
 
1796
                vector<string> physoutputs;
 
1797
 
 
1798
                _engine.get_physical_outputs (*t, physoutputs);
 
1799
                _engine.get_physical_inputs (*t, physinputs);
 
1800
 
 
1801
                if (!physinputs.empty() && connect_inputs) {
 
1802
                        uint32_t nphysical_in = physinputs.size();
 
1803
 
 
1804
                        DEBUG_TRACE (DEBUG::Graph,
 
1805
                                     string_compose("There are %1 physical inputs of type %2\n",
 
1806
                                                    nphysical_in, *t));
 
1807
 
 
1808
                        for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
 
1809
                                string port;
 
1810
 
 
1811
                                if (Config->get_input_auto_connect() & AutoConnectPhysical) {
 
1812
                                        DEBUG_TRACE (DEBUG::Graph,
 
1813
                                                     string_compose("Get index %1 + %2 % %3 = %4\n",
 
1814
                                                                    in_offset.get(*t), i, nphysical_in,
 
1815
                                                                    (in_offset.get(*t) + i) % nphysical_in));
 
1816
                                        port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
 
1817
                                }
 
1818
 
 
1819
                                DEBUG_TRACE (DEBUG::Graph,
 
1820
                                             string_compose("Connect route %1 IN to %2\n",
 
1821
                                                            route->name(), port));
 
1822
 
 
1823
                                if (!port.empty() && route->input()->connect (route->input()->ports().port(*t, i), port, this)) {
 
1824
                                        break;
 
1825
                                }
 
1826
 
 
1827
                                ChanCount one_added (*t, 1);
 
1828
                                existing_inputs += one_added;
 
1829
                        }
 
1830
                }
 
1831
 
 
1832
                if (!physoutputs.empty()) {
 
1833
                        uint32_t nphysical_out = physoutputs.size();
 
1834
                        for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
 
1835
                                string port;
 
1836
 
 
1837
                                if ((*t) == DataType::MIDI || Config->get_output_auto_connect() & AutoConnectPhysical) {
 
1838
                                        port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
 
1839
                                } else if ((*t) == DataType::AUDIO && Config->get_output_auto_connect() & AutoConnectMaster) {
 
1840
                                        /* master bus is audio only */
 
1841
                                        if (_master_out && _master_out->n_inputs().get(*t) > 0) {
 
1842
                                                port = _master_out->input()->ports().port(*t,
 
1843
                                                                i % _master_out->input()->n_ports().get(*t))->name();
 
1844
                                        }
 
1845
                                }
 
1846
 
 
1847
                                DEBUG_TRACE (DEBUG::Graph,
 
1848
                                             string_compose("Connect route %1 OUT to %2\n",
 
1849
                                                            route->name(), port));
 
1850
 
 
1851
                                if (!port.empty() && route->output()->connect (route->output()->ports().port(*t, i), port, this)) {
 
1852
                                        break;
 
1853
                                }
 
1854
 
 
1855
                                ChanCount one_added (*t, 1);
 
1856
                                existing_outputs += one_added;
 
1857
                        }
 
1858
                }
 
1859
        }
 
1860
}
 
1861
 
 
1862
/** Caller must not hold process lock
 
1863
 *  @param name_template string to use for the start of the name, or "" to use "Audio".
 
1864
 */
 
1865
list< boost::shared_ptr<AudioTrack> >
 
1866
Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, 
 
1867
                          uint32_t how_many, string name_template)
 
1868
{
 
1869
        char track_name[32];
 
1870
        uint32_t track_id = 0;
 
1871
        string port;
 
1872
        RouteList new_routes;
 
1873
        list<boost::shared_ptr<AudioTrack> > ret;
 
1874
 
 
1875
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
 
1876
 
 
1877
        while (how_many) {
 
1878
                if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
 
1879
                        error << "cannot find name for new audio track" << endmsg;
 
1880
                        goto failed;
 
1881
                }
 
1882
 
 
1883
                boost::shared_ptr<AudioTrack> track;
 
1884
 
 
1885
                try {
 
1886
                        track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
 
1887
 
 
1888
                        if (track->init ()) {
 
1889
                                goto failed;
 
1890
                        }
 
1891
 
 
1892
                        track->use_new_diskstream();
 
1893
 
 
1894
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
 
1895
                        // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
 
1896
#endif
 
1897
                        {
 
1898
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
1899
 
 
1900
                                if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
 
1901
                                        error << string_compose (
 
1902
                                                _("cannot configure %1 in/%2 out configuration for new audio track"),
 
1903
                                                input_channels, output_channels)
 
1904
                                              << endmsg;
 
1905
                                        goto failed;
 
1906
                                }
 
1907
 
 
1908
                                if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
 
1909
                                        error << string_compose (
 
1910
                                                _("cannot configure %1 in/%2 out configuration for new audio track"),
 
1911
                                                input_channels, output_channels)
 
1912
                                              << endmsg;
 
1913
                                        goto failed;
 
1914
                                }
 
1915
                        }
 
1916
 
 
1917
                        if (route_group) {
 
1918
                                route_group->add (track);
 
1919
                        }
 
1920
 
 
1921
                        track->non_realtime_input_change();
 
1922
 
 
1923
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
 
1924
                        if (Config->get_remote_model() == UserOrdered) {
 
1925
                                track->set_remote_control_id (next_control_id());
 
1926
                        }
 
1927
 
 
1928
                        new_routes.push_back (track);
 
1929
                        ret.push_back (track);
 
1930
                }
 
1931
 
 
1932
                catch (failed_constructor &err) {
 
1933
                        error << _("Session: could not create new audio track.") << endmsg;
 
1934
                        goto failed;
 
1935
                }
 
1936
 
 
1937
                catch (AudioEngine::PortRegistrationFailure& pfe) {
 
1938
 
 
1939
                        error << pfe.what() << endmsg;
 
1940
                        goto failed;
 
1941
                }
 
1942
 
 
1943
                --how_many;
 
1944
        }
 
1945
 
 
1946
  failed:
 
1947
        if (!new_routes.empty()) {
 
1948
                add_routes (new_routes, true, true, true);
 
1949
        }
 
1950
 
 
1951
        return ret;
 
1952
}
 
1953
 
 
1954
/** Caller must not hold process lock.
 
1955
 *  @param name_template string to use for the start of the name, or "" to use "Bus".
 
1956
 */
 
1957
RouteList
 
1958
Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
 
1959
{
 
1960
        char bus_name[32];
 
1961
        uint32_t bus_id = 0;
 
1962
        string port;
 
1963
        RouteList ret;
 
1964
 
 
1965
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
 
1966
        
 
1967
        while (how_many) {
 
1968
                if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
 
1969
                        error << "cannot find name for new audio bus" << endmsg;
 
1970
                        goto failure;
 
1971
                }
 
1972
 
 
1973
                try {
 
1974
                        boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
 
1975
 
 
1976
                        if (bus->init ()) {
 
1977
                                goto failure;
 
1978
                        }
 
1979
 
 
1980
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
 
1981
                        // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
 
1982
#endif
 
1983
                        {
 
1984
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
1985
 
 
1986
                                if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
 
1987
                                        error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
 
1988
                                                                 input_channels, output_channels)
 
1989
                                              << endmsg;
 
1990
                                        goto failure;
 
1991
                                }
 
1992
 
 
1993
 
 
1994
                                if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
 
1995
                                        error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
 
1996
                                                                 input_channels, output_channels)
 
1997
                                              << endmsg;
 
1998
                                        goto failure;
 
1999
                                }
 
2000
                        }
 
2001
 
 
2002
                        if (route_group) {
 
2003
                                route_group->add (bus);
 
2004
                        }
 
2005
                        if (Config->get_remote_model() == UserOrdered) {
 
2006
                                bus->set_remote_control_id (next_control_id());
 
2007
                        }
 
2008
 
 
2009
                        bus->add_internal_return ();
 
2010
 
 
2011
                        ret.push_back (bus);
 
2012
                        
 
2013
                        ARDOUR::GUIIdle ();
 
2014
                }
 
2015
 
 
2016
 
 
2017
                catch (failed_constructor &err) {
 
2018
                        error << _("Session: could not create new audio route.") << endmsg;
 
2019
                        goto failure;
 
2020
                }
 
2021
 
 
2022
                catch (AudioEngine::PortRegistrationFailure& pfe) {
 
2023
                        error << pfe.what() << endmsg;
 
2024
                        goto failure;
 
2025
                }
 
2026
 
 
2027
 
 
2028
                --how_many;
 
2029
        }
 
2030
 
 
2031
  failure:
 
2032
        if (!ret.empty()) {
 
2033
                add_routes (ret, false, true, true); // autoconnect outputs only
 
2034
        }
 
2035
 
 
2036
        return ret;
 
2037
 
 
2038
}
 
2039
 
 
2040
RouteList
 
2041
Session::new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name_base)
 
2042
{
 
2043
        RouteList ret;
 
2044
        uint32_t control_id;
 
2045
        XMLTree tree;
 
2046
        uint32_t number = 0;
 
2047
        const uint32_t being_added = how_many;
 
2048
 
 
2049
        if (!tree.read (template_path.c_str())) {
 
2050
                return ret;
 
2051
        }
 
2052
 
 
2053
        XMLNode* node = tree.root();
 
2054
 
 
2055
        IO::disable_connecting ();
 
2056
 
 
2057
        control_id = next_control_id ();
 
2058
 
 
2059
        while (how_many) {
 
2060
 
 
2061
                XMLNode node_copy (*node);
 
2062
 
 
2063
                /* Remove IDs of everything so that new ones are used */
 
2064
                node_copy.remove_property_recursively (X_("id"));
 
2065
 
 
2066
                try {
 
2067
                        char name[32];
 
2068
 
 
2069
                        if (!name_base.empty()) {
 
2070
 
 
2071
                                /* if we're adding more than one routes, force
 
2072
                                 * all the names of the new routes to be
 
2073
                                 * numbered, via the final parameter.
 
2074
                                 */
 
2075
 
 
2076
                                if (!find_route_name (name_base.c_str(), ++number, name, sizeof(name), (being_added > 1))) {
 
2077
                                        fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
 
2078
                                        /*NOTREACHDE*/
 
2079
                                }
 
2080
 
 
2081
                        } else {
 
2082
 
 
2083
                                string const route_name  = node_copy.property(X_("name"))->value ();
 
2084
                        
 
2085
                                /* generate a new name by adding a number to the end of the template name */
 
2086
                                if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) {
 
2087
                                        fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
 
2088
                                        /*NOTREACHED*/
 
2089
                                }
 
2090
                        }
 
2091
 
 
2092
                        /* set this name in the XML description that we are about to use */
 
2093
                        Route::set_name_in_state (node_copy, name);
 
2094
 
 
2095
                        /* trim bitslots from listen sends so that new ones are used */
 
2096
                        XMLNodeList children = node_copy.children ();
 
2097
                        for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
 
2098
                                if ((*i)->name() == X_("Processor")) {
 
2099
                                        XMLProperty* role = (*i)->property (X_("role"));
 
2100
                                        if (role && role->value() == X_("Listen")) {
 
2101
                                                (*i)->remove_property (X_("bitslot"));
 
2102
                                        }
 
2103
                                }
 
2104
                        }
 
2105
                        
 
2106
                        boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
 
2107
 
 
2108
                        if (route == 0) {
 
2109
                                error << _("Session: cannot create track/bus from template description") << endmsg;
 
2110
                                goto out;
 
2111
                        }
 
2112
 
 
2113
                        if (boost::dynamic_pointer_cast<Track>(route)) {
 
2114
                                /* force input/output change signals so that the new diskstream
 
2115
                                   picks up the configuration of the route. During session
 
2116
                                   loading this normally happens in a different way.
 
2117
                                */
 
2118
 
 
2119
                                Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
 
2120
 
 
2121
                                IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
 
2122
                                change.after = route->input()->n_ports();
 
2123
                                route->input()->changed (change, this);
 
2124
                                change.after = route->output()->n_ports();
 
2125
                                route->output()->changed (change, this);
 
2126
                        }
 
2127
 
 
2128
                        route->set_remote_control_id (control_id);
 
2129
                        ++control_id;
 
2130
 
 
2131
                        ret.push_back (route);
 
2132
                }
 
2133
 
 
2134
                catch (failed_constructor &err) {
 
2135
                        error << _("Session: could not create new route from template") << endmsg;
 
2136
                        goto out;
 
2137
                }
 
2138
 
 
2139
                catch (AudioEngine::PortRegistrationFailure& pfe) {
 
2140
                        error << pfe.what() << endmsg;
 
2141
                        goto out;
 
2142
                }
 
2143
 
 
2144
                --how_many;
 
2145
        }
 
2146
 
 
2147
  out:
 
2148
        if (!ret.empty()) {
 
2149
                add_routes (ret, true, true, true);
 
2150
                IO::enable_connecting ();
 
2151
        }
 
2152
 
 
2153
        return ret;
 
2154
}
 
2155
 
 
2156
void
 
2157
Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
 
2158
{
 
2159
        try {
 
2160
                PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
 
2161
                add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
 
2162
 
 
2163
        } catch (...) {
 
2164
                error << _("Adding new tracks/busses failed") << endmsg;
 
2165
        }
 
2166
 
 
2167
        graph_reordered ();
 
2168
 
 
2169
        update_latency (true);
 
2170
        update_latency (false);
 
2171
                
 
2172
        set_dirty();
 
2173
        
 
2174
        if (save) {
 
2175
                save_state (_current_snapshot_name);
 
2176
        }
 
2177
        
 
2178
        RouteAdded (new_routes); /* EMIT SIGNAL */
 
2179
}
 
2180
 
 
2181
void
 
2182
Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
 
2183
{
 
2184
        ChanCount existing_inputs;
 
2185
        ChanCount existing_outputs;
 
2186
        uint32_t order = next_control_id();
 
2187
 
 
2188
        count_existing_track_channels (existing_inputs, existing_outputs);
 
2189
 
 
2190
        {
 
2191
                RCUWriter<RouteList> writer (routes);
 
2192
                boost::shared_ptr<RouteList> r = writer.get_copy ();
 
2193
                r->insert (r->end(), new_routes.begin(), new_routes.end());
 
2194
 
 
2195
                /* if there is no control out and we're not in the middle of loading,
 
2196
                   resort the graph here. if there is a control out, we will resort
 
2197
                   toward the end of this method. if we are in the middle of loading,
 
2198
                   we will resort when done.
 
2199
                */
 
2200
 
 
2201
                if (!_monitor_out && IO::connecting_legal) {
 
2202
                        resort_routes_using (r);
 
2203
                }
 
2204
        }
 
2205
 
 
2206
        for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
 
2207
 
 
2208
                boost::weak_ptr<Route> wpr (*x);
 
2209
                boost::shared_ptr<Route> r (*x);
 
2210
 
 
2211
                r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
 
2212
                r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
 
2213
                r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
 
2214
                r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
 
2215
                r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
 
2216
                r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
 
2217
 
 
2218
                if (r->is_master()) {
 
2219
                        _master_out = r;
 
2220
                }
 
2221
 
 
2222
                if (r->is_monitor()) {
 
2223
                        _monitor_out = r;
 
2224
                }
 
2225
 
 
2226
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
 
2227
                if (tr) {
 
2228
                        tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
 
2229
                        track_playlist_changed (boost::weak_ptr<Track> (tr));
 
2230
                        tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
 
2231
 
 
2232
                        boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
 
2233
                        if (mt) {
 
2234
                                mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
 
2235
                                mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
 
2236
                        }
 
2237
                }
 
2238
 
 
2239
 
 
2240
                if (input_auto_connect || output_auto_connect) {
 
2241
                        auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
 
2242
                }
 
2243
 
 
2244
                /* order keys are a GUI responsibility but we need to set up
 
2245
                   reasonable defaults because they also affect the remote control
 
2246
                   ID in most situations.
 
2247
                */
 
2248
 
 
2249
                if (!r->has_order_key (EditorSort)) {
 
2250
                        if (r->is_auditioner()) {
 
2251
                                /* use an arbitrarily high value */
 
2252
                                r->set_order_key (EditorSort, UINT_MAX);
 
2253
                                r->set_order_key (MixerSort, UINT_MAX);
 
2254
                        } else {
 
2255
                                DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
 
2256
                                r->set_order_key (EditorSort, order);
 
2257
                                r->set_order_key (MixerSort, order);
 
2258
                                order++;
 
2259
                        }
 
2260
                }
 
2261
 
 
2262
                ARDOUR::GUIIdle ();
 
2263
        }
 
2264
 
 
2265
        if (_monitor_out && IO::connecting_legal) {
 
2266
                Glib::Threads::Mutex::Lock lm (_engine.process_lock());         
 
2267
                
 
2268
                for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
 
2269
                        if ((*x)->is_monitor()) {
 
2270
                                /* relax */
 
2271
                        } else if ((*x)->is_master()) {
 
2272
                                        /* relax */
 
2273
                        } else {
 
2274
                                (*x)->enable_monitor_send ();
 
2275
                        }
 
2276
                }
 
2277
        }
 
2278
}
 
2279
 
 
2280
void
 
2281
Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
 
2282
{
 
2283
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2284
        boost::shared_ptr<Send> s;
 
2285
 
 
2286
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2287
                if ((s = (*i)->internal_send_for (dest)) != 0) {
 
2288
                        s->amp()->gain_control()->set_value (0.0);
 
2289
                }
 
2290
        }
 
2291
}
 
2292
 
 
2293
void
 
2294
Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
 
2295
{
 
2296
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2297
        boost::shared_ptr<Send> s;
 
2298
 
 
2299
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2300
                if ((s = (*i)->internal_send_for (dest)) != 0) {
 
2301
                        s->amp()->gain_control()->set_value (1.0);
 
2302
                }
 
2303
        }
 
2304
}
 
2305
 
 
2306
void
 
2307
Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
 
2308
{
 
2309
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2310
        boost::shared_ptr<Send> s;
 
2311
 
 
2312
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2313
                if ((s = (*i)->internal_send_for (dest)) != 0) {
 
2314
                        s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
 
2315
                }
 
2316
        }
 
2317
}
 
2318
 
 
2319
/** @param include_buses true to add sends to buses and tracks, false for just tracks */
 
2320
void
 
2321
Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
 
2322
{
 
2323
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2324
        boost::shared_ptr<RouteList> t (new RouteList);
 
2325
 
 
2326
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2327
                /* no MIDI sends because there are no MIDI busses yet */
 
2328
                if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(*i)) {
 
2329
                        t->push_back (*i);
 
2330
                }
 
2331
        }
 
2332
 
 
2333
        add_internal_sends (dest, p, t);
 
2334
}
 
2335
 
 
2336
void
 
2337
Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
 
2338
{
 
2339
        for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
 
2340
                add_internal_send (dest, (*i)->before_processor_for_placement (p), *i);
 
2341
        }
 
2342
}
 
2343
 
 
2344
void
 
2345
Session::add_internal_send (boost::shared_ptr<Route> dest, int index, boost::shared_ptr<Route> sender)
 
2346
{
 
2347
        add_internal_send (dest, sender->before_processor_for_index (index), sender);
 
2348
}
 
2349
 
 
2350
void
 
2351
Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Processor> before, boost::shared_ptr<Route> sender)
 
2352
{
 
2353
        if (sender->is_monitor() || sender->is_master() || sender == dest || dest->is_monitor() || dest->is_master()) {
 
2354
                return;
 
2355
        }
 
2356
 
 
2357
        if (!dest->internal_return()) {
 
2358
                dest->add_internal_return ();
 
2359
        }
 
2360
 
 
2361
        sender->add_aux_send (dest, before);
 
2362
 
 
2363
        graph_reordered ();
 
2364
}
 
2365
 
 
2366
void
 
2367
Session::remove_route (boost::shared_ptr<Route> route)
 
2368
{
 
2369
        if (route == _master_out) {
 
2370
                return;
 
2371
        }
 
2372
 
 
2373
        route->set_solo (false, this);
 
2374
 
 
2375
        {
 
2376
                RCUWriter<RouteList> writer (routes);
 
2377
                boost::shared_ptr<RouteList> rs = writer.get_copy ();
 
2378
 
 
2379
                rs->remove (route);
 
2380
 
 
2381
                /* deleting the master out seems like a dumb
 
2382
                   idea, but its more of a UI policy issue
 
2383
                   than our concern.
 
2384
                */
 
2385
 
 
2386
                if (route == _master_out) {
 
2387
                        _master_out = boost::shared_ptr<Route> ();
 
2388
                }
 
2389
 
 
2390
                if (route == _monitor_out) {
 
2391
                        _monitor_out.reset ();
 
2392
                }
 
2393
 
 
2394
                /* writer goes out of scope, forces route list update */
 
2395
        }
 
2396
 
 
2397
        update_route_solo_state ();
 
2398
 
 
2399
        // We need to disconnect the route's inputs and outputs
 
2400
 
 
2401
        route->input()->disconnect (0);
 
2402
        route->output()->disconnect (0);
 
2403
 
 
2404
        /* if the route had internal sends sending to it, remove them */
 
2405
        if (route->internal_return()) {
 
2406
 
 
2407
                boost::shared_ptr<RouteList> r = routes.reader ();
 
2408
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2409
                        boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
 
2410
                        if (s) {
 
2411
                                (*i)->remove_processor (s);
 
2412
                        }
 
2413
                }
 
2414
        }
 
2415
 
 
2416
        boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
 
2417
        if (mt && mt->step_editing()) {
 
2418
                if (_step_editors > 0) {
 
2419
                        _step_editors--;
 
2420
                }
 
2421
        }
 
2422
 
 
2423
        update_latency_compensation ();
 
2424
        set_dirty();
 
2425
 
 
2426
        /* Re-sort routes to remove the graph's current references to the one that is
 
2427
         * going away, then flush old references out of the graph.
 
2428
         */
 
2429
 
 
2430
        resort_routes ();
 
2431
        if (_process_graph) {
 
2432
                _process_graph->clear_other_chain ();
 
2433
        }
 
2434
 
 
2435
        /* get rid of it from the dead wood collection in the route list manager */
 
2436
 
 
2437
        /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
 
2438
 
 
2439
        routes.flush ();
 
2440
 
 
2441
        /* try to cause everyone to drop their references */
 
2442
 
 
2443
        route->drop_references ();
 
2444
 
 
2445
        Route::RemoteControlIDChange(); /* EMIT SIGNAL */
 
2446
 
 
2447
        /* save the new state of the world */
 
2448
 
 
2449
        if (save_state (_current_snapshot_name)) {
 
2450
                save_history (_current_snapshot_name);
 
2451
        }
 
2452
}
 
2453
 
 
2454
void
 
2455
Session::route_mute_changed (void* /*src*/)
 
2456
{
 
2457
        set_dirty ();
 
2458
}
 
2459
 
 
2460
void
 
2461
Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
 
2462
{
 
2463
        boost::shared_ptr<Route> route = wpr.lock();
 
2464
        if (!route) {
 
2465
                error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
 
2466
                return;
 
2467
        }
 
2468
 
 
2469
        if (route->listening_via_monitor ()) {
 
2470
 
 
2471
                if (Config->get_exclusive_solo()) {
 
2472
                        /* new listen: disable all other listen */
 
2473
                        boost::shared_ptr<RouteList> r = routes.reader ();
 
2474
                        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2475
                                if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
 
2476
                                        continue;
 
2477
                                }
 
2478
                                (*i)->set_listen (false, this);
 
2479
                        }
 
2480
                }
 
2481
 
 
2482
                _listen_cnt++;
 
2483
 
 
2484
        } else if (_listen_cnt > 0) {
 
2485
 
 
2486
                _listen_cnt--;
 
2487
        }
 
2488
 
 
2489
        update_route_solo_state ();
 
2490
}
 
2491
void
 
2492
Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
 
2493
{
 
2494
        boost::shared_ptr<Route> route = wpr.lock ();
 
2495
 
 
2496
        if (!route) {
 
2497
                /* should not happen */
 
2498
                error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
 
2499
                return;
 
2500
        }
 
2501
 
 
2502
        bool send_changed = false;
 
2503
 
 
2504
        if (route->solo_isolated()) {
 
2505
                if (_solo_isolated_cnt == 0) {
 
2506
                        send_changed = true;
 
2507
                }
 
2508
                _solo_isolated_cnt++;
 
2509
        } else if (_solo_isolated_cnt > 0) {
 
2510
                _solo_isolated_cnt--;
 
2511
                if (_solo_isolated_cnt == 0) {
 
2512
                        send_changed = true;
 
2513
                }
 
2514
        }
 
2515
 
 
2516
        if (send_changed) {
 
2517
                IsolatedChanged (); /* EMIT SIGNAL */
 
2518
        }
 
2519
}
 
2520
 
 
2521
void
 
2522
Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
 
2523
{
 
2524
        DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
 
2525
 
 
2526
        if (!self_solo_change) {
 
2527
                // session doesn't care about changes to soloed-by-others
 
2528
                return;
 
2529
        }
 
2530
 
 
2531
        if (solo_update_disabled) {
 
2532
                // We know already
 
2533
                DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n");
 
2534
                return;
 
2535
        }
 
2536
 
 
2537
        boost::shared_ptr<Route> route = wpr.lock ();
 
2538
        assert (route);
 
2539
 
 
2540
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2541
        int32_t delta;
 
2542
 
 
2543
        if (route->self_soloed()) {
 
2544
                delta = 1;
 
2545
        } else {
 
2546
                delta = -1;
 
2547
        }
 
2548
 
 
2549
        RouteGroup* rg = route->route_group ();
 
2550
        bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
 
2551
 
 
2552
        if (delta == 1 && Config->get_exclusive_solo()) {
 
2553
                
 
2554
                /* new solo: disable all other solos, but not the group if its solo-enabled */
 
2555
 
 
2556
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2557
                        if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
 
2558
                            (leave_group_alone && ((*i)->route_group() == rg))) {
 
2559
                                continue;
 
2560
                        }
 
2561
                        (*i)->set_solo (false, this);
 
2562
                }
 
2563
        }
 
2564
 
 
2565
        DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta));
 
2566
 
 
2567
        solo_update_disabled = true;
 
2568
 
 
2569
        RouteList uninvolved;
 
2570
 
 
2571
        DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name()));
 
2572
 
 
2573
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2574
                bool via_sends_only;
 
2575
                bool in_signal_flow;
 
2576
 
 
2577
                if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
 
2578
                    (leave_group_alone && ((*i)->route_group() == rg))) {
 
2579
                        continue;
 
2580
                }
 
2581
 
 
2582
                in_signal_flow = false;
 
2583
 
 
2584
                DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name()));
 
2585
                
 
2586
                if ((*i)->feeds (route, &via_sends_only)) {
 
2587
                        DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name()));
 
2588
                        if (!via_sends_only) {
 
2589
                                if (!route->soloed_by_others_upstream()) {
 
2590
                                        (*i)->mod_solo_by_others_downstream (delta);
 
2591
                                }
 
2592
                        } else {
 
2593
                                DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name()));
 
2594
                        }
 
2595
                        in_signal_flow = true;
 
2596
                } else {
 
2597
                        DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name()));
 
2598
                }
 
2599
                
 
2600
                DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name()));
 
2601
 
 
2602
                if (route->feeds (*i, &via_sends_only)) {
 
2603
                        /* propagate solo upstream only if routing other than
 
2604
                           sends is involved, but do consider the other route
 
2605
                           (*i) to be part of the signal flow even if only
 
2606
                           sends are involved.
 
2607
                        */
 
2608
                        DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n",
 
2609
                                                                  route->name(),
 
2610
                                                                  (*i)->name(),
 
2611
                                                                  via_sends_only,
 
2612
                                                                  route->soloed_by_others_downstream(),
 
2613
                                                                  route->soloed_by_others_upstream()));
 
2614
                        if (!via_sends_only) {
 
2615
                                if (!route->soloed_by_others_downstream()) {
 
2616
                                        DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta));
 
2617
                                        (*i)->mod_solo_by_others_upstream (delta);
 
2618
                                } else {
 
2619
                                        DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n");
 
2620
                                }
 
2621
                        } else {
 
2622
                                DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name()));
 
2623
                        }
 
2624
                        in_signal_flow = true;
 
2625
                } else {
 
2626
                        DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n");
 
2627
                }
 
2628
 
 
2629
                if (!in_signal_flow) {
 
2630
                        uninvolved.push_back (*i);
 
2631
                }
 
2632
        }
 
2633
 
 
2634
        solo_update_disabled = false;
 
2635
        DEBUG_TRACE (DEBUG::Solo, "propagation complete\n");
 
2636
 
 
2637
        update_route_solo_state (r);
 
2638
 
 
2639
        /* now notify that the mute state of the routes not involved in the signal
 
2640
           pathway of the just-solo-changed route may have altered.
 
2641
        */
 
2642
 
 
2643
        for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
 
2644
                DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
 
2645
                (*i)->mute_changed (this);
 
2646
        }
 
2647
 
 
2648
        SoloChanged (); /* EMIT SIGNAL */
 
2649
        set_dirty();
 
2650
}
 
2651
 
 
2652
void
 
2653
Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
 
2654
{
 
2655
        /* now figure out if anything that matters is soloed (or is "listening")*/
 
2656
 
 
2657
        bool something_soloed = false;
 
2658
        uint32_t listeners = 0;
 
2659
        uint32_t isolated = 0;
 
2660
 
 
2661
        if (!r) {
 
2662
                r = routes.reader();
 
2663
        }
 
2664
 
 
2665
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2666
                if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner() && (*i)->self_soloed()) {
 
2667
                        something_soloed = true;
 
2668
                }
 
2669
 
 
2670
                if (!(*i)->is_auditioner() && (*i)->listening_via_monitor()) {
 
2671
                        if (Config->get_solo_control_is_listen_control()) {
 
2672
                                listeners++;
 
2673
                        } else {
 
2674
                                (*i)->set_listen (false, this);
 
2675
                        }
 
2676
                }
 
2677
 
 
2678
                if ((*i)->solo_isolated()) {
 
2679
                        isolated++;
 
2680
                }
 
2681
        }
 
2682
 
 
2683
        if (something_soloed != _non_soloed_outs_muted) {
 
2684
                _non_soloed_outs_muted = something_soloed;
 
2685
                SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
 
2686
        }
 
2687
 
 
2688
        _listen_cnt = listeners;
 
2689
 
 
2690
        if (isolated != _solo_isolated_cnt) {
 
2691
                _solo_isolated_cnt = isolated;
 
2692
                IsolatedChanged (); /* EMIT SIGNAL */
 
2693
        }
 
2694
 
 
2695
        DEBUG_TRACE (DEBUG::Solo, string_compose ("solo state updated by session, soloed? %1 listeners %2 isolated %3\n",
 
2696
                                                  something_soloed, listeners, isolated));
 
2697
}
 
2698
 
 
2699
boost::shared_ptr<RouteList>
 
2700
Session::get_routes_with_internal_returns() const
 
2701
{
 
2702
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2703
        boost::shared_ptr<RouteList> rl (new RouteList);
 
2704
 
 
2705
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2706
                if ((*i)->internal_return ()) {
 
2707
                        rl->push_back (*i);
 
2708
                }
 
2709
        }
 
2710
        return rl;
 
2711
}
 
2712
 
 
2713
bool
 
2714
Session::io_name_is_legal (const std::string& name)
 
2715
{
 
2716
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2717
 
 
2718
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2719
                if ((*i)->name() == name) {
 
2720
                        return false;
 
2721
                }
 
2722
 
 
2723
                if ((*i)->has_io_processor_named (name)) {
 
2724
                        return false;
 
2725
                }
 
2726
        }
 
2727
 
 
2728
        return true;
 
2729
}
 
2730
 
 
2731
void
 
2732
Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
 
2733
{
 
2734
        RouteList rl2;
 
2735
        vector<string> connections;
 
2736
 
 
2737
        /* if we are passed only a single route and we're not told to turn
 
2738
         * others off, then just do the simple thing.
 
2739
         */
 
2740
 
 
2741
        if (flip_others == false && rl->size() == 1) {
 
2742
                boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
 
2743
                if (mt) {
 
2744
                        mt->set_input_active (onoff);
 
2745
                        return;
 
2746
                }
 
2747
        }
 
2748
 
 
2749
        for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
 
2750
 
 
2751
                PortSet& ps ((*rt)->input()->ports());
 
2752
                
 
2753
                for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
 
2754
                        p->get_connections (connections);
 
2755
                }
 
2756
                
 
2757
                for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
 
2758
                        routes_using_input_from (*s, rl2);
 
2759
                }
 
2760
                
 
2761
                /* scan all relevant routes to see if others are on or off */
 
2762
                
 
2763
                bool others_are_already_on = false;
 
2764
                
 
2765
                for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
 
2766
 
 
2767
                        boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
 
2768
 
 
2769
                        if (!mt) {
 
2770
                                continue;
 
2771
                        }
 
2772
 
 
2773
                        if ((*r) != (*rt)) {
 
2774
                                if (mt->input_active()) {
 
2775
                                        others_are_already_on = true;
 
2776
                                }
 
2777
                        } else {
 
2778
                                /* this one needs changing */
 
2779
                                mt->set_input_active (onoff);
 
2780
                        }
 
2781
                }
 
2782
                
 
2783
                if (flip_others) {
 
2784
 
 
2785
                        /* globally reverse other routes */
 
2786
                        
 
2787
                        for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
 
2788
                                if ((*r) != (*rt)) {
 
2789
                                        boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
 
2790
                                        if (mt) {
 
2791
                                                mt->set_input_active (!others_are_already_on);
 
2792
                                        }
 
2793
                                }
 
2794
                        }
 
2795
                }
 
2796
        }
 
2797
}
 
2798
 
 
2799
void
 
2800
Session::routes_using_input_from (const string& str, RouteList& rl)
 
2801
{
 
2802
        boost::shared_ptr<RouteList> r = routes.reader();
 
2803
 
 
2804
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2805
                if ((*i)->input()->connected_to (str)) {
 
2806
                        rl.push_back (*i);
 
2807
                }
 
2808
        }
 
2809
}
 
2810
 
 
2811
boost::shared_ptr<Route>
 
2812
Session::route_by_name (string name)
 
2813
{
 
2814
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2815
 
 
2816
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2817
                if ((*i)->name() == name) {
 
2818
                        return *i;
 
2819
                }
 
2820
        }
 
2821
 
 
2822
        return boost::shared_ptr<Route> ((Route*) 0);
 
2823
}
 
2824
 
 
2825
boost::shared_ptr<Route>
 
2826
Session::route_by_id (PBD::ID id)
 
2827
{
 
2828
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2829
 
 
2830
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2831
                if ((*i)->id() == id) {
 
2832
                        return *i;
 
2833
                }
 
2834
        }
 
2835
 
 
2836
        return boost::shared_ptr<Route> ((Route*) 0);
 
2837
}
 
2838
 
 
2839
boost::shared_ptr<Track>
 
2840
Session::track_by_diskstream_id (PBD::ID id)
 
2841
{
 
2842
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2843
 
 
2844
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2845
                boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
 
2846
                if (t && t->using_diskstream_id (id)) {
 
2847
                        return t;
 
2848
                }
 
2849
        }
 
2850
 
 
2851
        return boost::shared_ptr<Track> ();
 
2852
}
 
2853
 
 
2854
boost::shared_ptr<Route>
 
2855
Session::route_by_remote_id (uint32_t id)
 
2856
{
 
2857
        boost::shared_ptr<RouteList> r = routes.reader ();
 
2858
 
 
2859
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
2860
                if ((*i)->remote_control_id() == id) {
 
2861
                        return *i;
 
2862
                }
 
2863
        }
 
2864
 
 
2865
        return boost::shared_ptr<Route> ((Route*) 0);
 
2866
}
 
2867
 
 
2868
void
 
2869
Session::playlist_region_added (boost::weak_ptr<Region> w)
 
2870
{
 
2871
        boost::shared_ptr<Region> r = w.lock ();
 
2872
        if (!r) {
 
2873
                return;
 
2874
        }
 
2875
 
 
2876
        /* These are the operations that are currently in progress... */
 
2877
        list<GQuark> curr = _current_trans_quarks;
 
2878
        curr.sort ();
 
2879
 
 
2880
        /* ...and these are the operations during which we want to update
 
2881
           the session range location markers.
 
2882
        */
 
2883
        list<GQuark> ops;
 
2884
        ops.push_back (Operations::capture);
 
2885
        ops.push_back (Operations::paste);
 
2886
        ops.push_back (Operations::duplicate_region);
 
2887
        ops.push_back (Operations::insert_file);
 
2888
        ops.push_back (Operations::insert_region);
 
2889
        ops.push_back (Operations::drag_region_brush);
 
2890
        ops.push_back (Operations::region_drag);
 
2891
        ops.push_back (Operations::selection_grab);
 
2892
        ops.push_back (Operations::region_fill);
 
2893
        ops.push_back (Operations::fill_selection);
 
2894
        ops.push_back (Operations::create_region);
 
2895
        ops.push_back (Operations::region_copy);
 
2896
        ops.push_back (Operations::fixed_time_region_copy);
 
2897
        ops.sort ();
 
2898
 
 
2899
        /* See if any of the current operations match the ones that we want */
 
2900
        list<GQuark> in;
 
2901
        set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
 
2902
 
 
2903
        /* If so, update the session range markers */
 
2904
        if (!in.empty ()) {
 
2905
                maybe_update_session_range (r->position (), r->last_frame ());
 
2906
        }
 
2907
}
 
2908
 
 
2909
/** Update the session range markers if a is before the current start or
 
2910
 *  b is after the current end.
 
2911
 */
 
2912
void
 
2913
Session::maybe_update_session_range (framepos_t a, framepos_t b)
 
2914
{
 
2915
        if (_state_of_the_state & Loading) {
 
2916
                return;
 
2917
        }
 
2918
 
 
2919
        if (_session_range_location == 0) {
 
2920
 
 
2921
                add_session_range_location (a, b);
 
2922
 
 
2923
        } else {
 
2924
 
 
2925
                if (a < _session_range_location->start()) {
 
2926
                        _session_range_location->set_start (a);
 
2927
                }
 
2928
 
 
2929
                if (b > _session_range_location->end()) {
 
2930
                        _session_range_location->set_end (b);
 
2931
                }
 
2932
        }
 
2933
}
 
2934
 
 
2935
void
 
2936
Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
 
2937
{
 
2938
        for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
 
2939
                maybe_update_session_range (i->to, i->to + i->length);
 
2940
        }
 
2941
}
 
2942
 
 
2943
void
 
2944
Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
 
2945
{
 
2946
        for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
 
2947
                maybe_update_session_range (i->from, i->to);
 
2948
        }
 
2949
}
 
2950
 
 
2951
/* Region management */
 
2952
 
 
2953
boost::shared_ptr<Region>
 
2954
Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
 
2955
{
 
2956
        const RegionFactory::RegionMap& regions (RegionFactory::regions());
 
2957
        RegionFactory::RegionMap::const_iterator i;
 
2958
        boost::shared_ptr<Region> region;
 
2959
 
 
2960
        Glib::Threads::Mutex::Lock lm (region_lock);
 
2961
 
 
2962
        for (i = regions.begin(); i != regions.end(); ++i) {
 
2963
 
 
2964
                region = i->second;
 
2965
 
 
2966
                if (region->whole_file()) {
 
2967
 
 
2968
                        if (child->source_equivalent (region)) {
 
2969
                                return region;
 
2970
                        }
 
2971
                }
 
2972
        }
 
2973
 
 
2974
        return boost::shared_ptr<Region> ();
 
2975
}
 
2976
 
 
2977
int
 
2978
Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
 
2979
{
 
2980
        set<boost::shared_ptr<Region> > relevant_regions;
 
2981
 
 
2982
        for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
 
2983
                RegionFactory::get_regions_using_source (*s, relevant_regions);
 
2984
        }
 
2985
 
 
2986
        for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
 
2987
                set<boost::shared_ptr<Region> >::iterator tmp;
 
2988
 
 
2989
                tmp = r;
 
2990
                ++tmp;
 
2991
 
 
2992
                playlists->destroy_region (*r);
 
2993
                RegionFactory::map_remove (*r);
 
2994
 
 
2995
                (*r)->drop_sources ();
 
2996
                (*r)->drop_references ();
 
2997
 
 
2998
                relevant_regions.erase (r);
 
2999
 
 
3000
                r = tmp;
 
3001
        }
 
3002
 
 
3003
        for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
 
3004
 
 
3005
                {
 
3006
                        Glib::Threads::Mutex::Lock ls (source_lock);
 
3007
                        /* remove from the main source list */
 
3008
                        sources.erase ((*s)->id());
 
3009
                }
 
3010
 
 
3011
                (*s)->mark_for_remove ();
 
3012
                (*s)->drop_references ();
 
3013
 
 
3014
                s = srcs.erase (s);
 
3015
        }
 
3016
 
 
3017
        return 0;
 
3018
}
 
3019
 
 
3020
int
 
3021
Session::remove_last_capture ()
 
3022
{
 
3023
        list<boost::shared_ptr<Source> > srcs;
 
3024
 
 
3025
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
3026
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
3027
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
3028
                if (!tr) {
 
3029
                        continue;
 
3030
                }
 
3031
 
 
3032
                list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
 
3033
 
 
3034
                if (!l.empty()) {
 
3035
                        srcs.insert (srcs.end(), l.begin(), l.end());
 
3036
                        l.clear ();
 
3037
                }
 
3038
        }
 
3039
 
 
3040
        destroy_sources (srcs);
 
3041
 
 
3042
        save_state (_current_snapshot_name);
 
3043
 
 
3044
        return 0;
 
3045
}
 
3046
 
 
3047
/* Source Management */
 
3048
 
 
3049
void
 
3050
Session::add_source (boost::shared_ptr<Source> source)
 
3051
{
 
3052
        pair<SourceMap::key_type, SourceMap::mapped_type> entry;
 
3053
        pair<SourceMap::iterator,bool> result;
 
3054
 
 
3055
        entry.first = source->id();
 
3056
        entry.second = source;
 
3057
 
 
3058
        {
 
3059
                Glib::Threads::Mutex::Lock lm (source_lock);
 
3060
                result = sources.insert (entry);
 
3061
        }
 
3062
 
 
3063
        if (result.second) {
 
3064
 
 
3065
                /* yay, new source */
 
3066
 
 
3067
                boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
 
3068
                
 
3069
                if (fs) {
 
3070
                        if (!fs->within_session()) {
 
3071
                                ensure_search_path_includes (Glib::path_get_dirname (fs->path()), fs->type());
 
3072
                        }
 
3073
                }
 
3074
                
 
3075
                set_dirty();
 
3076
 
 
3077
                boost::shared_ptr<AudioFileSource> afs;
 
3078
 
 
3079
                if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
 
3080
                        if (Config->get_auto_analyse_audio()) {
 
3081
                                Analyser::queue_source_for_analysis (source, false);
 
3082
                        }
 
3083
                }
 
3084
 
 
3085
                source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
 
3086
        }
 
3087
}
 
3088
 
 
3089
void
 
3090
Session::remove_source (boost::weak_ptr<Source> src)
 
3091
{
 
3092
        if (_state_of_the_state & Deletion) {
 
3093
                return;
 
3094
        }
 
3095
 
 
3096
        SourceMap::iterator i;
 
3097
        boost::shared_ptr<Source> source = src.lock();
 
3098
 
 
3099
        if (!source) {
 
3100
                return;
 
3101
        }
 
3102
 
 
3103
        {
 
3104
                Glib::Threads::Mutex::Lock lm (source_lock);
 
3105
 
 
3106
                if ((i = sources.find (source->id())) != sources.end()) {
 
3107
                        sources.erase (i);
 
3108
                }
 
3109
        }
 
3110
 
 
3111
        if (!(_state_of_the_state & InCleanup)) {
 
3112
 
 
3113
                /* save state so we don't end up with a session file
 
3114
                   referring to non-existent sources.
 
3115
                */
 
3116
 
 
3117
                save_state (_current_snapshot_name);
 
3118
        }
 
3119
}
 
3120
 
 
3121
boost::shared_ptr<Source>
 
3122
Session::source_by_id (const PBD::ID& id)
 
3123
{
 
3124
        Glib::Threads::Mutex::Lock lm (source_lock);
 
3125
        SourceMap::iterator i;
 
3126
        boost::shared_ptr<Source> source;
 
3127
 
 
3128
        if ((i = sources.find (id)) != sources.end()) {
 
3129
                source = i->second;
 
3130
        }
 
3131
 
 
3132
        return source;
 
3133
}
 
3134
 
 
3135
boost::shared_ptr<Source>
 
3136
Session::source_by_path_and_channel (const string& path, uint16_t chn)
 
3137
{
 
3138
        Glib::Threads::Mutex::Lock lm (source_lock);
 
3139
 
 
3140
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
 
3141
                boost::shared_ptr<AudioFileSource> afs
 
3142
                        = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
 
3143
 
 
3144
                if (afs && afs->path() == path && chn == afs->channel()) {
 
3145
                        return afs;
 
3146
                }
 
3147
        }
 
3148
        return boost::shared_ptr<Source>();
 
3149
}
 
3150
 
 
3151
uint32_t
 
3152
Session::count_sources_by_origin (const string& path)
 
3153
{
 
3154
        uint32_t cnt = 0;
 
3155
        Glib::Threads::Mutex::Lock lm (source_lock);
 
3156
 
 
3157
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
 
3158
                boost::shared_ptr<FileSource> fs
 
3159
                        = boost::dynamic_pointer_cast<FileSource>(i->second);
 
3160
 
 
3161
                if (fs && fs->origin() == path) {
 
3162
                        ++cnt;
 
3163
                }
 
3164
        }
 
3165
 
 
3166
        return cnt;
 
3167
}
 
3168
 
 
3169
 
 
3170
string
 
3171
Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
 
3172
{
 
3173
        string look_for;
 
3174
        string old_basename = PBD::basename_nosuffix (oldname);
 
3175
        string new_legalized = legalize_for_path (newname);
 
3176
 
 
3177
        /* note: we know (or assume) the old path is already valid */
 
3178
 
 
3179
        if (destructive) {
 
3180
 
 
3181
                /* destructive file sources have a name of the form:
 
3182
 
 
3183
                    /path/to/Tnnnn-NAME(%[LR])?.wav
 
3184
 
 
3185
                    the task here is to replace NAME with the new name.
 
3186
                */
 
3187
 
 
3188
                string dir;
 
3189
                string prefix;
 
3190
                string::size_type dash;
 
3191
 
 
3192
                dir = Glib::path_get_dirname (path);
 
3193
                path = Glib::path_get_basename (path);
 
3194
 
 
3195
                /* '-' is not a legal character for the NAME part of the path */
 
3196
 
 
3197
                if ((dash = path.find_last_of ('-')) == string::npos) {
 
3198
                        return "";
 
3199
                }
 
3200
 
 
3201
                prefix = path.substr (0, dash);
 
3202
 
 
3203
                path += prefix;
 
3204
                path += '-';
 
3205
                path += new_legalized;
 
3206
                path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
 
3207
                path = Glib::build_filename (dir, path);
 
3208
 
 
3209
        } else {
 
3210
 
 
3211
                /* non-destructive file sources have a name of the form:
 
3212
 
 
3213
                    /path/to/NAME-nnnnn(%[LR])?.ext
 
3214
 
 
3215
                    the task here is to replace NAME with the new name.
 
3216
                */
 
3217
 
 
3218
                string dir;
 
3219
                string suffix;
 
3220
                string::size_type dash;
 
3221
                string::size_type postfix;
 
3222
 
 
3223
                dir = Glib::path_get_dirname (path);
 
3224
                path = Glib::path_get_basename (path);
 
3225
 
 
3226
                /* '-' is not a legal character for the NAME part of the path */
 
3227
 
 
3228
                if ((dash = path.find_last_of ('-')) == string::npos) {
 
3229
                        return "";
 
3230
                }
 
3231
 
 
3232
                suffix = path.substr (dash+1);
 
3233
 
 
3234
                // Suffix is now everything after the dash. Now we need to eliminate
 
3235
                // the nnnnn part, which is done by either finding a '%' or a '.'
 
3236
 
 
3237
                postfix = suffix.find_last_of ("%");
 
3238
                if (postfix == string::npos) {
 
3239
                        postfix = suffix.find_last_of ('.');
 
3240
                }
 
3241
 
 
3242
                if (postfix != string::npos) {
 
3243
                        suffix = suffix.substr (postfix);
 
3244
                } else {
 
3245
                        error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
 
3246
                        return "";
 
3247
                }
 
3248
 
 
3249
                const uint32_t limit = 10000;
 
3250
                char buf[PATH_MAX+1];
 
3251
 
 
3252
                for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
 
3253
 
 
3254
                        snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
 
3255
 
 
3256
                        if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
 
3257
                                path = Glib::build_filename (dir, buf);
 
3258
                                break;
 
3259
                        }
 
3260
 
 
3261
                        path = "";
 
3262
                }
 
3263
 
 
3264
                if (path.empty()) {
 
3265
                        fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
 
3266
                                                 newname) << endl;
 
3267
                        /*NOTREACHED*/
 
3268
                }
 
3269
        }
 
3270
 
 
3271
        return path;
 
3272
}
 
3273
 
 
3274
/** Return the full path (in some session directory) for a new within-session source.
 
3275
 * \a name must be a session-unique name that does not contain slashes
 
3276
 *         (e.g. as returned by new_*_source_name)
 
3277
 */
 
3278
string
 
3279
Session::new_source_path_from_name (DataType type, const string& name)
 
3280
{
 
3281
        assert(name.find("/") == string::npos);
 
3282
 
 
3283
        SessionDirectory sdir(get_best_session_directory_for_new_source());
 
3284
 
 
3285
        std::string p;
 
3286
        if (type == DataType::AUDIO) {
 
3287
                p = sdir.sound_path();
 
3288
        } else if (type == DataType::MIDI) {
 
3289
                p = sdir.midi_path();
 
3290
        } else {
 
3291
                error << "Unknown source type, unable to create file path" << endmsg;
 
3292
                return "";
 
3293
        }
 
3294
 
 
3295
        return Glib::build_filename (p, name);
 
3296
}
 
3297
 
 
3298
string
 
3299
Session::peak_path (string base) const
 
3300
{
 
3301
        return Glib::build_filename (_session_dir->peak_path(), base + peakfile_suffix);
 
3302
}
 
3303
 
 
3304
/** Return a unique name based on \a base for a new internal audio source */
 
3305
string
 
3306
Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
 
3307
{
 
3308
        uint32_t cnt;
 
3309
        char buf[PATH_MAX+1];
 
3310
        const uint32_t limit = 10000;
 
3311
        string legalized;
 
3312
        string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
 
3313
 
 
3314
        buf[0] = '\0';
 
3315
        legalized = legalize_for_path (base);
 
3316
 
 
3317
        // Find a "version" of the base name that doesn't exist in any of the possible directories.
 
3318
        for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
 
3319
 
 
3320
                vector<space_and_path>::iterator i;
 
3321
                uint32_t existing = 0;
 
3322
 
 
3323
                for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
 
3324
 
 
3325
                        if (destructive) {
 
3326
 
 
3327
                                if (nchan < 2) {
 
3328
                                        snprintf (buf, sizeof(buf), "T%04d-%s%s",
 
3329
                                                  cnt, legalized.c_str(), ext.c_str());
 
3330
                                } else if (nchan == 2) {
 
3331
                                        if (chan == 0) {
 
3332
                                                snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
 
3333
                                                          cnt, legalized.c_str(), ext.c_str());
 
3334
                                        } else {
 
3335
                                                snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
 
3336
                                                          cnt, legalized.c_str(), ext.c_str());
 
3337
                                        }
 
3338
                                } else if (nchan < 26) {
 
3339
                                        snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
 
3340
                                                  cnt, legalized.c_str(), 'a' + chan, ext.c_str());
 
3341
                                } else {
 
3342
                                        snprintf (buf, sizeof(buf), "T%04d-%s%s",
 
3343
                                                  cnt, legalized.c_str(), ext.c_str());
 
3344
                                }
 
3345
 
 
3346
                        } else {
 
3347
 
 
3348
                                if (nchan < 2) {
 
3349
                                        snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
 
3350
                                } else if (nchan == 2) {
 
3351
                                        if (chan == 0) {
 
3352
                                                snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
 
3353
                                        } else {
 
3354
                                                snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
 
3355
                                        }
 
3356
                                } else if (nchan < 26) {
 
3357
                                        snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
 
3358
                                } else {
 
3359
                                        snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
 
3360
                                }
 
3361
                        }
 
3362
 
 
3363
                        SessionDirectory sdir((*i).path);
 
3364
 
 
3365
                        string spath = sdir.sound_path();
 
3366
 
 
3367
                        /* note that we search *without* the extension so that
 
3368
                           we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
 
3369
                           in the event that this new name is required for
 
3370
                           a file format change.
 
3371
                        */
 
3372
 
 
3373
                        if (matching_unsuffixed_filename_exists_in (spath, buf)) {
 
3374
                                existing++;
 
3375
                                break;
 
3376
                        }
 
3377
                }
 
3378
 
 
3379
                if (existing == 0) {
 
3380
                        break;
 
3381
                }
 
3382
 
 
3383
                if (cnt > limit) {
 
3384
                        error << string_compose(
 
3385
                                        _("There are already %1 recordings for %2, which I consider too many."),
 
3386
                                        limit, base) << endmsg;
 
3387
                        destroy ();
 
3388
                        throw failed_constructor();
 
3389
                }
 
3390
        }
 
3391
 
 
3392
        return Glib::path_get_basename (buf);
 
3393
}
 
3394
 
 
3395
/** Create a new within-session audio source */
 
3396
boost::shared_ptr<AudioFileSource>
 
3397
Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
 
3398
{
 
3399
        const string name    = new_audio_source_name (n, n_chans, chan, destructive);
 
3400
        const string path    = new_source_path_from_name(DataType::AUDIO, name);
 
3401
 
 
3402
        return boost::dynamic_pointer_cast<AudioFileSource> (
 
3403
                SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
 
3404
}
 
3405
 
 
3406
/** Return a unique name based on \a base for a new internal MIDI source */
 
3407
string
 
3408
Session::new_midi_source_name (const string& base)
 
3409
{
 
3410
        uint32_t cnt;
 
3411
        char buf[PATH_MAX+1];
 
3412
        const uint32_t limit = 10000;
 
3413
        string legalized;
 
3414
 
 
3415
        buf[0] = '\0';
 
3416
        legalized = legalize_for_path (base);
 
3417
 
 
3418
        // Find a "version" of the file name that doesn't exist in any of the possible directories.
 
3419
        for (cnt = 1; cnt <= limit; ++cnt) {
 
3420
 
 
3421
                vector<space_and_path>::iterator i;
 
3422
                uint32_t existing = 0;
 
3423
 
 
3424
                for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
 
3425
 
 
3426
                        SessionDirectory sdir((*i).path);
 
3427
 
 
3428
                        std::string p = Glib::build_filename (sdir.midi_path(), legalized);
 
3429
 
 
3430
                        snprintf (buf, sizeof(buf), "%s-%u.mid", p.c_str(), cnt);
 
3431
 
 
3432
                        if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
 
3433
                                existing++;
 
3434
                        }
 
3435
                }
 
3436
 
 
3437
                if (existing == 0) {
 
3438
                        break;
 
3439
                }
 
3440
 
 
3441
                if (cnt > limit) {
 
3442
                        error << string_compose(
 
3443
                                        _("There are already %1 recordings for %2, which I consider too many."),
 
3444
                                        limit, base) << endmsg;
 
3445
                        destroy ();
 
3446
                        throw failed_constructor();
 
3447
                }
 
3448
        }
 
3449
 
 
3450
        return Glib::path_get_basename(buf);
 
3451
}
 
3452
 
 
3453
 
 
3454
/** Create a new within-session MIDI source */
 
3455
boost::shared_ptr<MidiSource>
 
3456
Session::create_midi_source_for_session (Track* track, string const & n)
 
3457
{
 
3458
        /* try to use the existing write source for the track, to keep numbering sane
 
3459
         */
 
3460
 
 
3461
        if (track) {
 
3462
                /*MidiTrack* mt = dynamic_cast<Track*> (track);
 
3463
                  assert (mt);
 
3464
                */
 
3465
 
 
3466
                list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
 
3467
 
 
3468
                if (!l.empty()) {
 
3469
                        assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
 
3470
                        return boost::dynamic_pointer_cast<MidiSource> (l.front());
 
3471
                }
 
3472
        }
 
3473
 
 
3474
        const string name = new_midi_source_name (n);
 
3475
        const string path = new_source_path_from_name (DataType::MIDI, name);
 
3476
 
 
3477
        return boost::dynamic_pointer_cast<SMFSource> (
 
3478
                SourceFactory::createWritable (
 
3479
                        DataType::MIDI, *this, path, false, frame_rate()));
 
3480
}
 
3481
 
 
3482
 
 
3483
void
 
3484
Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
 
3485
{
 
3486
        if (playlist->hidden()) {
 
3487
                return;
 
3488
        }
 
3489
 
 
3490
        playlists->add (playlist);
 
3491
 
 
3492
        if (unused) {
 
3493
                playlist->release();
 
3494
        }
 
3495
 
 
3496
        set_dirty();
 
3497
}
 
3498
 
 
3499
void
 
3500
Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
 
3501
{
 
3502
        if (_state_of_the_state & Deletion) {
 
3503
                return;
 
3504
        }
 
3505
 
 
3506
        boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
 
3507
 
 
3508
        if (!playlist) {
 
3509
                return;
 
3510
        }
 
3511
 
 
3512
        playlists->remove (playlist);
 
3513
 
 
3514
        set_dirty();
 
3515
}
 
3516
 
 
3517
void
 
3518
Session::set_audition (boost::shared_ptr<Region> r)
 
3519
{
 
3520
        pending_audition_region = r;
 
3521
        add_post_transport_work (PostTransportAudition);
 
3522
        _butler->schedule_transport_work ();
 
3523
}
 
3524
 
 
3525
void
 
3526
Session::audition_playlist ()
 
3527
{
 
3528
        SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
 
3529
        ev->region.reset ();
 
3530
        queue_event (ev);
 
3531
}
 
3532
 
 
3533
void
 
3534
Session::non_realtime_set_audition ()
 
3535
{
 
3536
        assert (pending_audition_region);
 
3537
        auditioner->audition_region (pending_audition_region);
 
3538
        pending_audition_region.reset ();
 
3539
        AuditionActive (true); /* EMIT SIGNAL */
 
3540
}
 
3541
 
 
3542
void
 
3543
Session::audition_region (boost::shared_ptr<Region> r)
 
3544
{
 
3545
        SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
 
3546
        ev->region = r;
 
3547
        queue_event (ev);
 
3548
}
 
3549
 
 
3550
void
 
3551
Session::cancel_audition ()
 
3552
{
 
3553
        if (auditioner->auditioning()) {
 
3554
                auditioner->cancel_audition ();
 
3555
                AuditionActive (false); /* EMIT SIGNAL */
 
3556
        }
 
3557
}
 
3558
 
 
3559
bool
 
3560
Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
 
3561
{
 
3562
        if (a->is_monitor()) {
 
3563
                return true;
 
3564
        }
 
3565
        if (b->is_monitor()) {
 
3566
                return false;
 
3567
        }
 
3568
        return a->order_key (MixerSort) < b->order_key (MixerSort);
 
3569
}
 
3570
 
 
3571
bool
 
3572
Session::is_auditioning () const
 
3573
{
 
3574
        /* can be called before we have an auditioner object */
 
3575
        if (auditioner) {
 
3576
                return auditioner->auditioning();
 
3577
        } else {
 
3578
                return false;
 
3579
        }
 
3580
}
 
3581
 
 
3582
void
 
3583
Session::graph_reordered ()
 
3584
{
 
3585
        /* don't do this stuff if we are setting up connections
 
3586
           from a set_state() call or creating new tracks. Ditto for deletion.
 
3587
        */
 
3588
 
 
3589
        if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
 
3590
                return;
 
3591
        }
 
3592
 
 
3593
        /* every track/bus asked for this to be handled but it was deferred because
 
3594
           we were connecting. do it now.
 
3595
        */
 
3596
 
 
3597
        request_input_change_handling ();
 
3598
 
 
3599
        resort_routes ();
 
3600
 
 
3601
        /* force all diskstreams to update their capture offset values to
 
3602
           reflect any changes in latencies within the graph.
 
3603
        */
 
3604
 
 
3605
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
3606
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
3607
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
3608
                if (tr) {
 
3609
                        tr->set_capture_offset ();
 
3610
                }
 
3611
        }
 
3612
}
 
3613
 
 
3614
/** @return Number of frames that there is disk space available to write,
 
3615
 *  if known.
 
3616
 */
 
3617
boost::optional<framecnt_t>
 
3618
Session::available_capture_duration ()
 
3619
{
 
3620
        Glib::Threads::Mutex::Lock lm (space_lock);
 
3621
 
 
3622
        if (_total_free_4k_blocks_uncertain) {
 
3623
                return boost::optional<framecnt_t> ();
 
3624
        }
 
3625
        
 
3626
        float sample_bytes_on_disk = 4.0; // keep gcc happy
 
3627
 
 
3628
        switch (config.get_native_file_data_format()) {
 
3629
        case FormatFloat:
 
3630
                sample_bytes_on_disk = 4.0;
 
3631
                break;
 
3632
 
 
3633
        case FormatInt24:
 
3634
                sample_bytes_on_disk = 3.0;
 
3635
                break;
 
3636
 
 
3637
        case FormatInt16:
 
3638
                sample_bytes_on_disk = 2.0;
 
3639
                break;
 
3640
 
 
3641
        default:
 
3642
                /* impossible, but keep some gcc versions happy */
 
3643
                fatal << string_compose (_("programming error: %1"),
 
3644
                                         X_("illegal native file data format"))
 
3645
                      << endmsg;
 
3646
                /*NOTREACHED*/
 
3647
        }
 
3648
 
 
3649
        double scale = 4096.0 / sample_bytes_on_disk;
 
3650
 
 
3651
        if (_total_free_4k_blocks * scale > (double) max_framecnt) {
 
3652
                return max_framecnt;
 
3653
        }
 
3654
 
 
3655
        return (framecnt_t) floor (_total_free_4k_blocks * scale);
 
3656
}
 
3657
 
 
3658
void
 
3659
Session::add_bundle (boost::shared_ptr<Bundle> bundle)
 
3660
{
 
3661
        {
 
3662
                RCUWriter<BundleList> writer (_bundles);
 
3663
                boost::shared_ptr<BundleList> b = writer.get_copy ();
 
3664
                b->push_back (bundle);
 
3665
        }
 
3666
 
 
3667
        BundleAdded (bundle); /* EMIT SIGNAL */
 
3668
 
 
3669
        set_dirty();
 
3670
}
 
3671
 
 
3672
void
 
3673
Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
 
3674
{
 
3675
        bool removed = false;
 
3676
 
 
3677
        {
 
3678
                RCUWriter<BundleList> writer (_bundles);
 
3679
                boost::shared_ptr<BundleList> b = writer.get_copy ();
 
3680
                BundleList::iterator i = find (b->begin(), b->end(), bundle);
 
3681
 
 
3682
                if (i != b->end()) {
 
3683
                        b->erase (i);
 
3684
                        removed = true;
 
3685
                }
 
3686
        }
 
3687
 
 
3688
        if (removed) {
 
3689
                 BundleRemoved (bundle); /* EMIT SIGNAL */
 
3690
        }
 
3691
 
 
3692
        set_dirty();
 
3693
}
 
3694
 
 
3695
boost::shared_ptr<Bundle>
 
3696
Session::bundle_by_name (string name) const
 
3697
{
 
3698
        boost::shared_ptr<BundleList> b = _bundles.reader ();
 
3699
 
 
3700
        for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
 
3701
                if ((*i)->name() == name) {
 
3702
                        return* i;
 
3703
                }
 
3704
        }
 
3705
 
 
3706
        return boost::shared_ptr<Bundle> ();
 
3707
}
 
3708
 
 
3709
void
 
3710
Session::tempo_map_changed (const PropertyChange&)
 
3711
{
 
3712
        clear_clicks ();
 
3713
 
 
3714
        playlists->update_after_tempo_map_change ();
 
3715
 
 
3716
        _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
 
3717
 
 
3718
        set_dirty ();
 
3719
}
 
3720
 
 
3721
void
 
3722
Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
 
3723
{
 
3724
        for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
 
3725
                (*i)->recompute_frames_from_bbt ();
 
3726
        }
 
3727
}
 
3728
 
 
3729
/** Ensures that all buffers (scratch, send, silent, etc) are allocated for
 
3730
 * the given count with the current block size.
 
3731
 */
 
3732
void
 
3733
Session::ensure_buffers (ChanCount howmany)
 
3734
{
 
3735
        BufferManager::ensure_buffers (howmany);
 
3736
}
 
3737
 
 
3738
void
 
3739
Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
 
3740
{
 
3741
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
3742
                buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
 
3743
        }
 
3744
}
 
3745
 
 
3746
uint32_t
 
3747
Session::next_insert_id ()
 
3748
{
 
3749
        /* this doesn't really loop forever. just think about it */
 
3750
 
 
3751
        while (true) {
 
3752
                for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
 
3753
                        if (!insert_bitset[n]) {
 
3754
                                insert_bitset[n] = true;
 
3755
                                return n;
 
3756
 
 
3757
                        }
 
3758
                }
 
3759
 
 
3760
                /* none available, so resize and try again */
 
3761
 
 
3762
                insert_bitset.resize (insert_bitset.size() + 16, false);
 
3763
        }
 
3764
}
 
3765
 
 
3766
uint32_t
 
3767
Session::next_send_id ()
 
3768
{
 
3769
        /* this doesn't really loop forever. just think about it */
 
3770
 
 
3771
        while (true) {
 
3772
                for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
 
3773
                        if (!send_bitset[n]) {
 
3774
                                send_bitset[n] = true;
 
3775
                                return n;
 
3776
 
 
3777
                        }
 
3778
                }
 
3779
 
 
3780
                /* none available, so resize and try again */
 
3781
 
 
3782
                send_bitset.resize (send_bitset.size() + 16, false);
 
3783
        }
 
3784
}
 
3785
 
 
3786
uint32_t
 
3787
Session::next_aux_send_id ()
 
3788
{
 
3789
        /* this doesn't really loop forever. just think about it */
 
3790
 
 
3791
        while (true) {
 
3792
                for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < aux_send_bitset.size(); ++n) {
 
3793
                        if (!aux_send_bitset[n]) {
 
3794
                                aux_send_bitset[n] = true;
 
3795
                                return n;
 
3796
 
 
3797
                        }
 
3798
                }
 
3799
 
 
3800
                /* none available, so resize and try again */
 
3801
 
 
3802
                aux_send_bitset.resize (aux_send_bitset.size() + 16, false);
 
3803
        }
 
3804
}
 
3805
 
 
3806
uint32_t
 
3807
Session::next_return_id ()
 
3808
{
 
3809
        /* this doesn't really loop forever. just think about it */
 
3810
 
 
3811
        while (true) {
 
3812
                for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
 
3813
                        if (!return_bitset[n]) {
 
3814
                                return_bitset[n] = true;
 
3815
                                return n;
 
3816
 
 
3817
                        }
 
3818
                }
 
3819
 
 
3820
                /* none available, so resize and try again */
 
3821
 
 
3822
                return_bitset.resize (return_bitset.size() + 16, false);
 
3823
        }
 
3824
}
 
3825
 
 
3826
void
 
3827
Session::mark_send_id (uint32_t id)
 
3828
{
 
3829
        if (id >= send_bitset.size()) {
 
3830
                send_bitset.resize (id+16, false);
 
3831
        }
 
3832
        if (send_bitset[id]) {
 
3833
                warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
 
3834
        }
 
3835
        send_bitset[id] = true;
 
3836
}
 
3837
 
 
3838
void
 
3839
Session::mark_aux_send_id (uint32_t id)
 
3840
{
 
3841
        if (id >= aux_send_bitset.size()) {
 
3842
                aux_send_bitset.resize (id+16, false);
 
3843
        }
 
3844
        if (aux_send_bitset[id]) {
 
3845
                warning << string_compose (_("aux send ID %1 appears to be in use already"), id) << endmsg;
 
3846
        }
 
3847
        aux_send_bitset[id] = true;
 
3848
}
 
3849
 
 
3850
void
 
3851
Session::mark_return_id (uint32_t id)
 
3852
{
 
3853
        if (id >= return_bitset.size()) {
 
3854
                return_bitset.resize (id+16, false);
 
3855
        }
 
3856
        if (return_bitset[id]) {
 
3857
                warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
 
3858
        }
 
3859
        return_bitset[id] = true;
 
3860
}
 
3861
 
 
3862
void
 
3863
Session::mark_insert_id (uint32_t id)
 
3864
{
 
3865
        if (id >= insert_bitset.size()) {
 
3866
                insert_bitset.resize (id+16, false);
 
3867
        }
 
3868
        if (insert_bitset[id]) {
 
3869
                warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
 
3870
        }
 
3871
        insert_bitset[id] = true;
 
3872
}
 
3873
 
 
3874
void
 
3875
Session::unmark_send_id (uint32_t id)
 
3876
{
 
3877
        if (id < send_bitset.size()) {
 
3878
                send_bitset[id] = false;
 
3879
        }
 
3880
}
 
3881
 
 
3882
void
 
3883
Session::unmark_aux_send_id (uint32_t id)
 
3884
{
 
3885
        if (id < aux_send_bitset.size()) {
 
3886
                aux_send_bitset[id] = false;
 
3887
        }
 
3888
}
 
3889
 
 
3890
void
 
3891
Session::unmark_return_id (uint32_t id)
 
3892
{
 
3893
        if (id < return_bitset.size()) {
 
3894
                return_bitset[id] = false;
 
3895
        }
 
3896
}
 
3897
 
 
3898
void
 
3899
Session::unmark_insert_id (uint32_t id)
 
3900
{
 
3901
        if (id < insert_bitset.size()) {
 
3902
                insert_bitset[id] = false;
 
3903
        }
 
3904
}
 
3905
 
 
3906
void
 
3907
Session::reset_native_file_format ()
 
3908
{
 
3909
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
3910
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
3911
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
3912
                if (tr) {
 
3913
                        /* don't save state as we do this, there's no point
 
3914
                         */
 
3915
 
 
3916
                        _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
 
3917
                        tr->reset_write_sources (false);
 
3918
                        _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
 
3919
                }
 
3920
        }
 
3921
}
 
3922
 
 
3923
bool
 
3924
Session::route_name_unique (string n) const
 
3925
{
 
3926
        boost::shared_ptr<RouteList> r = routes.reader ();
 
3927
 
 
3928
        for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
 
3929
                if ((*i)->name() == n) {
 
3930
                        return false;
 
3931
                }
 
3932
        }
 
3933
 
 
3934
        return true;
 
3935
}
 
3936
 
 
3937
bool
 
3938
Session::route_name_internal (string n) const
 
3939
{
 
3940
        if (auditioner && auditioner->name() == n) {
 
3941
                return true;
 
3942
        }
 
3943
 
 
3944
        if (_click_io && _click_io->name() == n) {
 
3945
                return true;
 
3946
        }
 
3947
 
 
3948
        return false;
 
3949
}
 
3950
 
 
3951
int
 
3952
Session::freeze_all (InterThreadInfo& itt)
 
3953
{
 
3954
        boost::shared_ptr<RouteList> r = routes.reader ();
 
3955
 
 
3956
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
3957
 
 
3958
                boost::shared_ptr<Track> t;
 
3959
 
 
3960
                if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
 
3961
                        /* XXX this is wrong because itt.progress will keep returning to zero at the start
 
3962
                           of every track.
 
3963
                        */
 
3964
                        t->freeze_me (itt);
 
3965
                }
 
3966
        }
 
3967
 
 
3968
        return 0;
 
3969
}
 
3970
 
 
3971
boost::shared_ptr<Region>
 
3972
Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
 
3973
                          bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
 
3974
                          InterThreadInfo& itt, 
 
3975
                          boost::shared_ptr<Processor> endpoint, bool include_endpoint,
 
3976
                          bool for_export)
 
3977
{
 
3978
        boost::shared_ptr<Region> result;
 
3979
        boost::shared_ptr<Playlist> playlist;
 
3980
        boost::shared_ptr<AudioFileSource> fsource;
 
3981
        uint32_t x;
 
3982
        char buf[PATH_MAX+1];
 
3983
        ChanCount diskstream_channels (track.n_channels());
 
3984
        framepos_t position;
 
3985
        framecnt_t this_chunk;
 
3986
        framepos_t to_do;
 
3987
        BufferSet buffers;
 
3988
        SessionDirectory sdir(get_best_session_directory_for_new_source ());
 
3989
        const string sound_dir = sdir.sound_path();
 
3990
        framepos_t len = end - start;
 
3991
        bool need_block_size_reset = false;
 
3992
        string ext;
 
3993
        ChanCount const max_proc = track.max_processor_streams ();
 
3994
 
 
3995
        if (end <= start) {
 
3996
                error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
 
3997
                                         end, start) << endmsg;
 
3998
                return result;
 
3999
        }
 
4000
 
 
4001
        const framecnt_t chunk_size = (256 * 1024)/4;
 
4002
 
 
4003
        // block all process callback handling
 
4004
 
 
4005
        block_processing ();
 
4006
 
 
4007
        /* call tree *MUST* hold route_lock */
 
4008
 
 
4009
        if ((playlist = track.playlist()) == 0) {
 
4010
                goto out;
 
4011
        }
 
4012
 
 
4013
        ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
 
4014
 
 
4015
        for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
 
4016
 
 
4017
                for (x = 0; x < 99999; ++x) {
 
4018
                        snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 "%s", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1, ext.c_str());
 
4019
                        if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
 
4020
                                break;
 
4021
                        }
 
4022
                }
 
4023
 
 
4024
                if (x == 99999) {
 
4025
                        error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
 
4026
                        goto out;
 
4027
                }
 
4028
 
 
4029
                try {
 
4030
                        fsource = boost::dynamic_pointer_cast<AudioFileSource> (
 
4031
                                SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
 
4032
                }
 
4033
 
 
4034
                catch (failed_constructor& err) {
 
4035
                        error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
 
4036
                        goto out;
 
4037
                }
 
4038
 
 
4039
                srcs.push_back (fsource);
 
4040
        }
 
4041
 
 
4042
        /* tell redirects that care that we are about to use a much larger
 
4043
         * blocksize. this will flush all plugins too, so that they are ready
 
4044
         * to be used for this process.
 
4045
         */
 
4046
 
 
4047
        need_block_size_reset = true;
 
4048
        track.set_block_size (chunk_size);
 
4049
 
 
4050
        position = start;
 
4051
        to_do = len;
 
4052
 
 
4053
        /* create a set of reasonably-sized buffers */
 
4054
        buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
 
4055
        buffers.set_count (max_proc);
 
4056
 
 
4057
        for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
 
4058
                boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
4059
                if (afs)
 
4060
                        afs->prepare_for_peakfile_writes ();
 
4061
        }
 
4062
 
 
4063
        while (to_do && !itt.cancel) {
 
4064
 
 
4065
                this_chunk = min (to_do, chunk_size);
 
4066
 
 
4067
                if (track.export_stuff (buffers, start, this_chunk, endpoint, include_endpoint, for_export)) {
 
4068
                        goto out;
 
4069
                }
 
4070
 
 
4071
                uint32_t n = 0;
 
4072
                for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
 
4073
                        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
4074
 
 
4075
                        if (afs) {
 
4076
                                if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
 
4077
                                        goto out;
 
4078
                                }
 
4079
                        }
 
4080
                }
 
4081
 
 
4082
                start += this_chunk;
 
4083
                to_do -= this_chunk;
 
4084
 
 
4085
                itt.progress = (float) (1.0 - ((double) to_do / len));
 
4086
 
 
4087
        }
 
4088
 
 
4089
        if (!itt.cancel) {
 
4090
 
 
4091
                time_t now;
 
4092
                struct tm* xnow;
 
4093
                time (&now);
 
4094
                xnow = localtime (&now);
 
4095
 
 
4096
                for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
 
4097
                        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
4098
 
 
4099
                        if (afs) {
 
4100
                                afs->update_header (position, *xnow, now);
 
4101
                                afs->flush_header ();
 
4102
                        }
 
4103
                }
 
4104
 
 
4105
                /* construct a region to represent the bounced material */
 
4106
 
 
4107
                PropertyList plist;
 
4108
 
 
4109
                plist.add (Properties::start, 0);
 
4110
                plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
 
4111
                plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
 
4112
 
 
4113
                result = RegionFactory::create (srcs, plist);
 
4114
 
 
4115
        }
 
4116
 
 
4117
  out:
 
4118
        if (!result) {
 
4119
                for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
 
4120
                        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
4121
 
 
4122
                        if (afs) {
 
4123
                                afs->mark_for_remove ();
 
4124
                        }
 
4125
 
 
4126
                        (*src)->drop_references ();
 
4127
                }
 
4128
 
 
4129
        } else {
 
4130
                for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
 
4131
                        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
4132
 
 
4133
                        if (afs)
 
4134
                                afs->done_with_peakfile_writes ();
 
4135
                }
 
4136
        }
 
4137
 
 
4138
 
 
4139
        if (need_block_size_reset) {
 
4140
                track.set_block_size (get_block_size());
 
4141
        }
 
4142
 
 
4143
        unblock_processing ();
 
4144
 
 
4145
        return result;
 
4146
}
 
4147
 
 
4148
gain_t*
 
4149
Session::gain_automation_buffer() const
 
4150
{
 
4151
        return ProcessThread::gain_automation_buffer ();
 
4152
}
 
4153
 
 
4154
gain_t*
 
4155
Session::send_gain_automation_buffer() const
 
4156
{
 
4157
        return ProcessThread::send_gain_automation_buffer ();
 
4158
}
 
4159
 
 
4160
pan_t**
 
4161
Session::pan_automation_buffer() const
 
4162
{
 
4163
        return ProcessThread::pan_automation_buffer ();
 
4164
}
 
4165
 
 
4166
BufferSet&
 
4167
Session::get_silent_buffers (ChanCount count)
 
4168
{
 
4169
        return ProcessThread::get_silent_buffers (count);
 
4170
}
 
4171
 
 
4172
BufferSet&
 
4173
Session::get_scratch_buffers (ChanCount count, bool silence)
 
4174
{
 
4175
        return ProcessThread::get_scratch_buffers (count, silence);
 
4176
}
 
4177
 
 
4178
BufferSet&
 
4179
Session::get_route_buffers (ChanCount count, bool silence)
 
4180
{
 
4181
        return ProcessThread::get_route_buffers (count, silence);
 
4182
}
 
4183
 
 
4184
 
 
4185
BufferSet&
 
4186
Session::get_mix_buffers (ChanCount count)
 
4187
{
 
4188
        return ProcessThread::get_mix_buffers (count);
 
4189
}
 
4190
 
 
4191
uint32_t
 
4192
Session::ntracks () const
 
4193
{
 
4194
        uint32_t n = 0;
 
4195
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4196
 
 
4197
        for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
 
4198
                if (boost::dynamic_pointer_cast<Track> (*i)) {
 
4199
                        ++n;
 
4200
                }
 
4201
        }
 
4202
 
 
4203
        return n;
 
4204
}
 
4205
 
 
4206
uint32_t
 
4207
Session::nbusses () const
 
4208
{
 
4209
        uint32_t n = 0;
 
4210
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4211
 
 
4212
        for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
 
4213
                if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
 
4214
                        ++n;
 
4215
                }
 
4216
        }
 
4217
 
 
4218
        return n;
 
4219
}
 
4220
 
 
4221
void
 
4222
Session::add_automation_list(AutomationList *al)
 
4223
{
 
4224
        automation_lists[al->id()] = al;
 
4225
}
 
4226
 
 
4227
/** @return true if there is at least one record-enabled track, otherwise false */
 
4228
bool
 
4229
Session::have_rec_enabled_track () const
 
4230
{
 
4231
        return g_atomic_int_get (const_cast<gint*>(&_have_rec_enabled_track)) == 1;
 
4232
}
 
4233
 
 
4234
/** Update the state of our rec-enabled tracks flag */
 
4235
void
 
4236
Session::update_have_rec_enabled_track ()
 
4237
{
 
4238
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
4239
        RouteList::iterator i = rl->begin();
 
4240
        while (i != rl->end ()) {
 
4241
 
 
4242
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
4243
                if (tr && tr->record_enabled ()) {
 
4244
                        break;
 
4245
                }
 
4246
 
 
4247
                ++i;
 
4248
        }
 
4249
 
 
4250
        int const old = g_atomic_int_get (&_have_rec_enabled_track);
 
4251
 
 
4252
        g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
 
4253
 
 
4254
        if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
 
4255
                RecordStateChanged (); /* EMIT SIGNAL */
 
4256
        }
 
4257
}
 
4258
 
 
4259
void
 
4260
Session::listen_position_changed ()
 
4261
{
 
4262
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4263
 
 
4264
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4265
                (*i)->listen_position_changed ();
 
4266
        }
 
4267
}
 
4268
 
 
4269
void
 
4270
Session::solo_control_mode_changed ()
 
4271
{
 
4272
        /* cancel all solo or all listen when solo control mode changes */
 
4273
 
 
4274
        if (soloing()) {
 
4275
                set_solo (get_routes(), false);
 
4276
        } else if (listening()) {
 
4277
                set_listen (get_routes(), false);
 
4278
        }
 
4279
}
 
4280
 
 
4281
/** Called when a property of one of our route groups changes */
 
4282
void
 
4283
Session::route_group_property_changed (RouteGroup* rg)
 
4284
{
 
4285
        RouteGroupPropertyChanged (rg); /* EMIT SIGNAL */
 
4286
}
 
4287
 
 
4288
/** Called when a route is added to one of our route groups */
 
4289
void
 
4290
Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
 
4291
{
 
4292
        RouteAddedToRouteGroup (rg, r);
 
4293
}
 
4294
 
 
4295
/** Called when a route is removed from one of our route groups */
 
4296
void
 
4297
Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr<Route> r)
 
4298
{
 
4299
        RouteRemovedFromRouteGroup (rg, r);
 
4300
}
 
4301
 
 
4302
boost::shared_ptr<RouteList>
 
4303
Session::get_routes_with_regions_at (framepos_t const p) const
 
4304
{
 
4305
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4306
        boost::shared_ptr<RouteList> rl (new RouteList);
 
4307
 
 
4308
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4309
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
4310
                if (!tr) {
 
4311
                        continue;
 
4312
                }
 
4313
 
 
4314
                boost::shared_ptr<Playlist> pl = tr->playlist ();
 
4315
                if (!pl) {
 
4316
                        continue;
 
4317
                }
 
4318
 
 
4319
                if (pl->has_region_at (p)) {
 
4320
                        rl->push_back (*i);
 
4321
                }
 
4322
        }
 
4323
 
 
4324
        return rl;
 
4325
}
 
4326
 
 
4327
void
 
4328
Session::goto_end ()
 
4329
{
 
4330
        if (_session_range_location) {
 
4331
                request_locate (_session_range_location->end(), false);
 
4332
        } else {
 
4333
                request_locate (0, false);
 
4334
        }
 
4335
}
 
4336
 
 
4337
void
 
4338
Session::goto_start ()
 
4339
{
 
4340
        if (_session_range_location) {
 
4341
                request_locate (_session_range_location->start(), false);
 
4342
        } else {
 
4343
                request_locate (0, false);
 
4344
        }
 
4345
}
 
4346
 
 
4347
framepos_t
 
4348
Session::current_start_frame () const
 
4349
{
 
4350
        return _session_range_location ? _session_range_location->start() : 0;
 
4351
}
 
4352
 
 
4353
framepos_t
 
4354
Session::current_end_frame () const
 
4355
{
 
4356
        return _session_range_location ? _session_range_location->end() : 0;
 
4357
}
 
4358
 
 
4359
void
 
4360
Session::add_session_range_location (framepos_t start, framepos_t end)
 
4361
{
 
4362
        _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
 
4363
        _locations->add (_session_range_location);
 
4364
}
 
4365
 
 
4366
void
 
4367
Session::step_edit_status_change (bool yn)
 
4368
{
 
4369
        bool send = false;
 
4370
 
 
4371
        bool val = false;
 
4372
        if (yn) {
 
4373
                send = (_step_editors == 0);
 
4374
                val = true;
 
4375
 
 
4376
                _step_editors++;
 
4377
        } else {
 
4378
                send = (_step_editors == 1);
 
4379
                val = false;
 
4380
 
 
4381
                if (_step_editors > 0) {
 
4382
                        _step_editors--;
 
4383
                }
 
4384
        }
 
4385
 
 
4386
        if (send) {
 
4387
                StepEditStatusChange (val);
 
4388
        }
 
4389
}
 
4390
 
 
4391
 
 
4392
void
 
4393
Session::start_time_changed (framepos_t old)
 
4394
{
 
4395
        /* Update the auto loop range to match the session range
 
4396
           (unless the auto loop range has been changed by the user)
 
4397
        */
 
4398
 
 
4399
        Location* s = _locations->session_range_location ();
 
4400
        if (s == 0) {
 
4401
                return;
 
4402
        }
 
4403
 
 
4404
        Location* l = _locations->auto_loop_location ();
 
4405
 
 
4406
        if (l && l->start() == old) {
 
4407
                l->set_start (s->start(), true);
 
4408
        }
 
4409
}
 
4410
 
 
4411
void
 
4412
Session::end_time_changed (framepos_t old)
 
4413
{
 
4414
        /* Update the auto loop range to match the session range
 
4415
           (unless the auto loop range has been changed by the user)
 
4416
        */
 
4417
 
 
4418
        Location* s = _locations->session_range_location ();
 
4419
        if (s == 0) {
 
4420
                return;
 
4421
        }
 
4422
 
 
4423
        Location* l = _locations->auto_loop_location ();
 
4424
 
 
4425
        if (l && l->end() == old) {
 
4426
                l->set_end (s->end(), true);
 
4427
        }
 
4428
}
 
4429
 
 
4430
string
 
4431
Session::source_search_path (DataType type) const
 
4432
{
 
4433
        vector<string> s;
 
4434
 
 
4435
        if (session_dirs.size() == 1) {
 
4436
                switch (type) {
 
4437
                case DataType::AUDIO:
 
4438
                        s.push_back (_session_dir->sound_path());
 
4439
                        break;
 
4440
                case DataType::MIDI:
 
4441
                        s.push_back (_session_dir->midi_path());
 
4442
                        break;
 
4443
                }
 
4444
        } else {
 
4445
                for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
 
4446
                        SessionDirectory sdir (i->path);
 
4447
                        switch (type) {
 
4448
                        case DataType::AUDIO:
 
4449
                                s.push_back (sdir.sound_path());
 
4450
                                break;
 
4451
                        case DataType::MIDI:
 
4452
                                s.push_back (sdir.midi_path());
 
4453
                                break;
 
4454
                        }
 
4455
                }
 
4456
        }
 
4457
 
 
4458
        if (type == DataType::AUDIO) {
 
4459
                const string sound_path_2X = _session_dir->sound_path_2X();
 
4460
                if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
 
4461
                        if (find (s.begin(), s.end(), sound_path_2X) == s.end()) {
 
4462
                                s.push_back (sound_path_2X);
 
4463
                        }
 
4464
                }
 
4465
        }
 
4466
 
 
4467
        /* now check the explicit (possibly user-specified) search path
 
4468
         */
 
4469
 
 
4470
        vector<string> dirs;
 
4471
 
 
4472
        switch (type) {
 
4473
        case DataType::AUDIO:
 
4474
                split (config.get_audio_search_path (), dirs, ':');
 
4475
                break;
 
4476
        case DataType::MIDI:
 
4477
                split (config.get_midi_search_path (), dirs, ':');
 
4478
                break;
 
4479
        }
 
4480
 
 
4481
        for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
 
4482
                if (find (s.begin(), s.end(), *i) == s.end()) {
 
4483
                        s.push_back (*i);
 
4484
                }
 
4485
        }
 
4486
        
 
4487
        string search_path;
 
4488
 
 
4489
        for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) {
 
4490
                if (!search_path.empty()) {
 
4491
                        search_path += ':';
 
4492
                }
 
4493
                search_path += *si;
 
4494
        }
 
4495
 
 
4496
        return search_path;
 
4497
}
 
4498
 
 
4499
void
 
4500
Session::ensure_search_path_includes (const string& path, DataType type)
 
4501
{
 
4502
        string search_path;
 
4503
        vector<string> dirs;
 
4504
 
 
4505
        if (path == ".") {
 
4506
                return;
 
4507
        }
 
4508
 
 
4509
        switch (type) {
 
4510
        case DataType::AUDIO:
 
4511
                search_path = config.get_audio_search_path ();
 
4512
                break;
 
4513
        case DataType::MIDI:
 
4514
                search_path = config.get_midi_search_path ();
 
4515
                break;
 
4516
        }
 
4517
 
 
4518
        split (search_path, dirs, ':');
 
4519
 
 
4520
        for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
 
4521
                /* No need to add this new directory if it has the same inode as
 
4522
                   an existing one; checking inode rather than name prevents duplicated
 
4523
                   directories when we are using symlinks.
 
4524
 
 
4525
                   On Windows, I think we could just do if (*i == path) here.
 
4526
                */
 
4527
                if (PBD::equivalent_paths (*i, path)) {
 
4528
                        return;
 
4529
                }
 
4530
        }
 
4531
 
 
4532
        if (!search_path.empty()) {
 
4533
                search_path += ':';
 
4534
        }
 
4535
 
 
4536
        search_path += path;
 
4537
 
 
4538
        switch (type) {
 
4539
        case DataType::AUDIO:
 
4540
                config.set_audio_search_path (search_path);
 
4541
                break;
 
4542
        case DataType::MIDI:
 
4543
                config.set_midi_search_path (search_path);
 
4544
                break;
 
4545
        }
 
4546
}
 
4547
 
 
4548
boost::shared_ptr<Speakers>
 
4549
Session::get_speakers()
 
4550
{
 
4551
        return _speakers;
 
4552
}
 
4553
 
 
4554
list<string>
 
4555
Session::unknown_processors () const
 
4556
{
 
4557
        list<string> p;
 
4558
 
 
4559
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4560
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4561
                list<string> t = (*i)->unknown_processors ();
 
4562
                copy (t.begin(), t.end(), back_inserter (p));
 
4563
        }
 
4564
 
 
4565
        p.sort ();
 
4566
        p.unique ();
 
4567
 
 
4568
        return p;
 
4569
}
 
4570
 
 
4571
void
 
4572
Session::update_latency (bool playback)
 
4573
{
 
4574
        DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
 
4575
 
 
4576
        if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
 
4577
                return;
 
4578
        }
 
4579
 
 
4580
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4581
        framecnt_t max_latency = 0;
 
4582
 
 
4583
        if (playback) {
 
4584
                /* reverse the list so that we work backwards from the last route to run to the first */
 
4585
                RouteList* rl = routes.reader().get();
 
4586
                r.reset (new RouteList (*rl));
 
4587
                reverse (r->begin(), r->end());
 
4588
        }
 
4589
 
 
4590
        /* compute actual latency values for the given direction and store them all in per-port
 
4591
           structures. this will also publish the same values (to JACK) so that computation of latency
 
4592
           for routes can consistently use public latency values.
 
4593
        */
 
4594
 
 
4595
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4596
                max_latency = max (max_latency, (*i)->set_private_port_latencies (playback));
 
4597
        }
 
4598
 
 
4599
        /* because we latency compensate playback, our published playback latencies should
 
4600
           be the same for all output ports - all material played back by ardour has
 
4601
           the same latency, whether its caused by plugins or by latency compensation. since
 
4602
           these may differ from the values computed above, reset all playback port latencies
 
4603
           to the same value.
 
4604
        */
 
4605
 
 
4606
        DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
 
4607
 
 
4608
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4609
                (*i)->set_public_port_latencies (max_latency, playback);
 
4610
        }
 
4611
 
 
4612
        if (playback) {
 
4613
 
 
4614
                post_playback_latency ();
 
4615
 
 
4616
        } else {
 
4617
 
 
4618
                post_capture_latency ();
 
4619
        }
 
4620
 
 
4621
        DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n");
 
4622
}
 
4623
 
 
4624
void
 
4625
Session::post_playback_latency ()
 
4626
{
 
4627
        set_worst_playback_latency ();
 
4628
 
 
4629
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4630
 
 
4631
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4632
                if (!(*i)->is_auditioner() && ((*i)->active())) {
 
4633
                        _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
 
4634
                }
 
4635
        }
 
4636
 
 
4637
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4638
                (*i)->set_latency_compensation (_worst_track_latency);
 
4639
        }
 
4640
}
 
4641
 
 
4642
void
 
4643
Session::post_capture_latency ()
 
4644
{
 
4645
        set_worst_capture_latency ();
 
4646
 
 
4647
        /* reflect any changes in capture latencies into capture offsets
 
4648
         */
 
4649
 
 
4650
        boost::shared_ptr<RouteList> rl = routes.reader();
 
4651
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
4652
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
4653
                if (tr) {
 
4654
                        tr->set_capture_offset ();
 
4655
                }
 
4656
        }
 
4657
}
 
4658
 
 
4659
void
 
4660
Session::initialize_latencies ()
 
4661
{
 
4662
        {
 
4663
                Glib::Threads::Mutex::Lock lm (_engine.process_lock());
 
4664
                update_latency (false);
 
4665
                update_latency (true);
 
4666
        }
 
4667
 
 
4668
        set_worst_io_latencies ();
 
4669
}
 
4670
 
 
4671
void
 
4672
Session::set_worst_io_latencies ()
 
4673
{
 
4674
        set_worst_playback_latency ();
 
4675
        set_worst_capture_latency ();
 
4676
}
 
4677
 
 
4678
void
 
4679
Session::set_worst_playback_latency ()
 
4680
{
 
4681
        if (_state_of_the_state & (InitialConnecting|Deletion)) {
 
4682
                return;
 
4683
        }
 
4684
 
 
4685
        _worst_output_latency = 0;
 
4686
 
 
4687
        if (!_engine.connected()) {
 
4688
                return;
 
4689
        }
 
4690
 
 
4691
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4692
 
 
4693
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4694
                _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
 
4695
        }
 
4696
 
 
4697
        DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency));
 
4698
}
 
4699
 
 
4700
void
 
4701
Session::set_worst_capture_latency ()
 
4702
{
 
4703
        if (_state_of_the_state & (InitialConnecting|Deletion)) {
 
4704
                return;
 
4705
        }
 
4706
 
 
4707
        _worst_input_latency = 0;
 
4708
 
 
4709
        if (!_engine.connected()) {
 
4710
                return;
 
4711
        }
 
4712
 
 
4713
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4714
 
 
4715
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4716
                _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
 
4717
        }
 
4718
 
 
4719
        DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency));
 
4720
}
 
4721
 
 
4722
void
 
4723
Session::update_latency_compensation (bool force_whole_graph)
 
4724
{
 
4725
        bool some_track_latency_changed = false;
 
4726
 
 
4727
        if (_state_of_the_state & (InitialConnecting|Deletion)) {
 
4728
                return;
 
4729
        }
 
4730
 
 
4731
        DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n");
 
4732
 
 
4733
        _worst_track_latency = 0;
 
4734
 
 
4735
        boost::shared_ptr<RouteList> r = routes.reader ();
 
4736
 
 
4737
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4738
                if (!(*i)->is_auditioner() && ((*i)->active())) {
 
4739
                        framecnt_t tl;
 
4740
                        if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
 
4741
                                some_track_latency_changed = true;
 
4742
                        }
 
4743
                        _worst_track_latency = max (tl, _worst_track_latency);
 
4744
                }
 
4745
        }
 
4746
 
 
4747
        DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency,
 
4748
                                                     (some_track_latency_changed ? "yes" : "no")));
 
4749
 
 
4750
        DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n");
 
4751
        
 
4752
        if (some_track_latency_changed || force_whole_graph)  {
 
4753
                _engine.update_latencies ();
 
4754
        }
 
4755
 
 
4756
 
 
4757
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
4758
                boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
4759
                if (!tr) {
 
4760
                        continue;
 
4761
                }
 
4762
                tr->set_capture_offset ();
 
4763
        }
 
4764
}
 
4765
 
 
4766
char
 
4767
Session::session_name_is_legal (const string& path)
 
4768
{
 
4769
        char illegal_chars[] = { '/', '\\', ':', ';', '\0' };
 
4770
 
 
4771
        for (int i = 0; illegal_chars[i]; ++i) {
 
4772
                if (path.find (illegal_chars[i]) != string::npos) {
 
4773
                        return illegal_chars[i];
 
4774
                }
 
4775
        }
 
4776
 
 
4777
        return 0;
 
4778
}
 
4779
 
 
4780
uint32_t 
 
4781
Session::next_control_id () const
 
4782
{
 
4783
        int subtract = 0;
 
4784
 
 
4785
        /* the monitor bus remote ID is in a different
 
4786
         * "namespace" than regular routes. its existence doesn't
 
4787
         * affect normal (low) numbered routes.
 
4788
         */
 
4789
 
 
4790
        if (_monitor_out) {
 
4791
                subtract++;
 
4792
        }
 
4793
 
 
4794
        return nroutes() - subtract;
 
4795
}
 
4796
 
 
4797
void
 
4798
Session::notify_remote_id_change ()
 
4799
{
 
4800
        if (deletion_in_progress()) {
 
4801
                return;
 
4802
        }
 
4803
 
 
4804
        switch (Config->get_remote_model()) {
 
4805
        case MixerSort:
 
4806
        case EditorSort:
 
4807
                Route::RemoteControlIDChange (); /* EMIT SIGNAL */
 
4808
                break;
 
4809
        default:
 
4810
                break;
 
4811
        }
 
4812
}
 
4813
 
 
4814
void
 
4815
Session::sync_order_keys (RouteSortOrderKey sort_key_changed)
 
4816
{
 
4817
        if (deletion_in_progress()) {
 
4818
                return;
 
4819
        }
 
4820
 
 
4821
        /* tell everyone that something has happened to the sort keys
 
4822
           and let them sync up with the change(s)
 
4823
           this will give objects that manage the sort order keys the
 
4824
           opportunity to keep them in sync if they wish to.
 
4825
        */
 
4826
 
 
4827
        DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("Sync Order Keys, based on %1\n", enum_2_string (sort_key_changed)));
 
4828
 
 
4829
        Route::SyncOrderKeys (sort_key_changed); /* EMIT SIGNAL */
 
4830
 
 
4831
        DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
 
4832
}
 
4833
 
 
4834
bool
 
4835
Session::operation_in_progress (GQuark op) const
 
4836
{
 
4837
        return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
 
4838
}
 
4839
 
 
4840
boost::shared_ptr<Port>
 
4841
Session::ltc_input_port () const
 
4842
{
 
4843
        return _ltc_input->nth (0);
 
4844
}
 
4845
 
 
4846
boost::shared_ptr<Port>
 
4847
Session::ltc_output_port () const
 
4848
{
 
4849
        return _ltc_output->nth (0);
 
4850
}
 
4851
 
 
4852
void
 
4853
Session::reconnect_ltc_input ()
 
4854
{
 
4855
        if (_ltc_input) {
 
4856
 
 
4857
                string src = Config->get_ltc_source_port();
 
4858
 
 
4859
                _ltc_input->disconnect (this);
 
4860
 
 
4861
                if (src != _("None") && !src.empty())  {
 
4862
                        _ltc_input->nth (0)->connect (src);
 
4863
                }
 
4864
        }
 
4865
}
 
4866
 
 
4867
void
 
4868
Session::reconnect_ltc_output ()
 
4869
{
 
4870
        if (_ltc_output) {
 
4871
 
 
4872
#if 0
 
4873
                string src = Config->get_ltc_sink_port();
 
4874
 
 
4875
                _ltc_output->disconnect (this);
 
4876
 
 
4877
                if (src != _("None") && !src.empty())  {
 
4878
                        _ltc_output->nth (0)->connect (src);
 
4879
                }
 
4880
#endif
 
4881
        }
 
4882
}