Add Import from session -functionality
[ardour.git] / libs / ardour / session.cc
1 /*
2     Copyright (C) 1999-2004 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 <algorithm>
21 #include <string>
22 #include <vector>
23 #include <sstream>
24 #include <fstream>
25 #include <cstdio> /* sprintf(3) ... grrr */
26 #include <cmath>
27 #include <cerrno>
28 #include <unistd.h>
29 #include <limits.h>
30
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
33
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
37
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
45
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/session_metadata.h>
51 #include <ardour/utils.h>
52 #include <ardour/audio_diskstream.h>
53 #include <ardour/audioplaylist.h>
54 #include <ardour/audioregion.h>
55 #include <ardour/audiofilesource.h>
56 #include <ardour/midi_diskstream.h>
57 #include <ardour/midi_playlist.h>
58 #include <ardour/midi_region.h>
59 #include <ardour/smf_source.h>
60 #include <ardour/auditioner.h>
61 #include <ardour/recent_sessions.h>
62 #include <ardour/io_processor.h>
63 #include <ardour/send.h>
64 #include <ardour/processor.h>
65 #include <ardour/plugin_insert.h>
66 #include <ardour/port_insert.h>
67 #include <ardour/auto_bundle.h>
68 #include <ardour/slave.h>
69 #include <ardour/tempo.h>
70 #include <ardour/audio_track.h>
71 #include <ardour/midi_track.h>
72 #include <ardour/cycle_timer.h>
73 #include <ardour/named_selection.h>
74 #include <ardour/crossfade.h>
75 #include <ardour/playlist.h>
76 #include <ardour/click.h>
77 #include <ardour/data_type.h>
78 #include <ardour/buffer_set.h>
79 #include <ardour/source_factory.h>
80 #include <ardour/region_factory.h>
81 #include <ardour/filename_extensions.h>
82 #include <ardour/session_directory.h>
83 #include <ardour/tape_file_matcher.h>
84 #include <ardour/analyser.h>
85
86 #ifdef HAVE_LIBLO
87 #include <ardour/osc.h>
88 #endif
89
90 #include "i18n.h"
91
92 using namespace std;
93 using namespace ARDOUR;
94 using namespace PBD;
95 using boost::shared_ptr;
96
97 #ifdef __x86_64__
98 static const int CPU_CACHE_ALIGN = 64;
99 #else
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
101 #endif
102
103 bool Session::_disable_all_loaded_plugins = false;
104
105 Session::compute_peak_t          Session::compute_peak          = 0;
106 Session::find_peaks_t            Session::find_peaks            = 0;
107 Session::apply_gain_to_buffer_t  Session::apply_gain_to_buffer  = 0;
108 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
109 Session::mix_buffers_no_gain_t   Session::mix_buffers_no_gain   = 0;
110
111 sigc::signal<void,std::string> Session::Dialog;
112 sigc::signal<int> Session::AskAboutPendingState;
113 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
114 sigc::signal<void> Session::SendFeedback;
115
116 sigc::signal<void> Session::SMPTEOffsetChanged;
117 sigc::signal<void> Session::StartTimeChanged;
118 sigc::signal<void> Session::EndTimeChanged;
119 sigc::signal<void> Session::AutoBindingOn;
120 sigc::signal<void> Session::AutoBindingOff;
121 sigc::signal<void, std::string, std::string> Session::Exported;
122
123 Session::Session (AudioEngine &eng,
124                   const string& fullpath,
125                   const string& snapshot_name,
126                   string mix_template)
127
128         : _engine (eng),
129           _scratch_buffers(new BufferSet()),
130           _silent_buffers(new BufferSet()),
131           _mix_buffers(new BufferSet()),
132           _mmc_port (default_mmc_port),
133           _mtc_port (default_mtc_port),
134           _midi_port (default_midi_port),
135           _midi_clock_port (default_midi_clock_port),
136           _session_dir (new SessionDirectory(fullpath)),
137           pending_events (2048),
138           post_transport_work((PostTransportWork)0),
139           _send_smpte_update (false),
140           midi_requests (128),
141           diskstreams (new DiskstreamList),
142           routes (new RouteList),
143           auditioner ((Auditioner*) 0),
144           _total_free_4k_blocks (0),
145           _bundle_xml_node (0),
146           _click_io ((IO*) 0),
147           main_outs (0),
148           _metadata (new SessionMetadata())
149 {
150         bool new_session;
151
152         if (!eng.connected()) {
153                 throw failed_constructor();
154         }
155
156         cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
157
158         n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159         n_physical_inputs =  _engine.n_physical_inputs(DataType::AUDIO);
160
161         first_stage_init (fullpath, snapshot_name);
162
163         new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
164
165         if (new_session) {
166                 if (create (new_session, mix_template, compute_initial_length())) {
167                         destroy ();
168                         throw failed_constructor ();
169                 }
170         }
171
172         if (second_stage_init (new_session)) {
173                 destroy ();
174                 throw failed_constructor ();
175         }
176
177         store_recent_sessions(_name, _path);
178
179         bool was_dirty = dirty();
180
181         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
182
183         Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
184
185         if (was_dirty) {
186                 DirtyChanged (); /* EMIT SIGNAL */
187         }
188 }
189
190 Session::Session (AudioEngine &eng,
191                   string fullpath,
192                   string snapshot_name,
193                   AutoConnectOption input_ac,
194                   AutoConnectOption output_ac,
195                   uint32_t control_out_channels,
196                   uint32_t master_out_channels,
197                   uint32_t requested_physical_in,
198                   uint32_t requested_physical_out,
199                   nframes_t initial_length)
200
201         : _engine (eng),
202           _scratch_buffers(new BufferSet()),
203           _silent_buffers(new BufferSet()),
204           _mix_buffers(new BufferSet()),
205           _mmc_port (default_mmc_port),
206           _mtc_port (default_mtc_port),
207           _midi_port (default_midi_port),
208           _midi_clock_port (default_midi_clock_port),
209           _session_dir ( new SessionDirectory(fullpath)),
210           pending_events (2048),
211           post_transport_work((PostTransportWork)0),
212           _send_smpte_update (false),
213           midi_requests (16),
214           diskstreams (new DiskstreamList),
215           routes (new RouteList),
216           _total_free_4k_blocks (0),
217           _bundle_xml_node (0),
218           main_outs (0)
219
220 {
221         bool new_session;
222
223         if (!eng.connected()) {
224                 throw failed_constructor();
225         }
226
227         cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
228
229         n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
230         n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
231
232         if (n_physical_inputs) {
233                 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
234         }
235
236         if (n_physical_outputs) {
237                 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
238         }
239
240         first_stage_init (fullpath, snapshot_name);
241
242         new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
243
244         if (new_session) {
245                 if (create (new_session, string(), initial_length)) {
246                         destroy ();
247                         throw failed_constructor ();
248                 }
249         }
250
251         {
252                 /* set up Master Out and Control Out if necessary */
253
254                 RouteList rl;
255                 int control_id = 1;
256
257                 if (control_out_channels) {
258                         shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
259                         r->set_remote_control_id (control_id++);
260
261                         rl.push_back (r);
262                 }
263
264                 if (master_out_channels) {
265                         shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
266                         r->set_remote_control_id (control_id);
267
268                         rl.push_back (r);
269                 } else {
270                         /* prohibit auto-connect to master, because there isn't one */
271                         output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
272                 }
273
274                 if (!rl.empty()) {
275                         add_routes (rl, false);
276                 }
277
278         }
279
280         Config->set_input_auto_connect (input_ac);
281         Config->set_output_auto_connect (output_ac);
282
283         if (second_stage_init (new_session)) {
284                 destroy ();
285                 throw failed_constructor ();
286         }
287
288         store_recent_sessions (_name, _path);
289
290         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
291
292         Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
293 }
294
295 Session::~Session ()
296 {
297         destroy ();
298 }
299
300 void
301 Session::destroy ()
302 {
303         /* if we got to here, leaving pending capture state around
304            is a mistake.
305         */
306
307         remove_pending_capture_state ();
308
309         _state_of_the_state = StateOfTheState (CannotSave|Deletion);
310
311         _engine.remove_session ();
312
313         GoingAway (); /* EMIT SIGNAL */
314
315         /* do this */
316
317         notify_callbacks ();
318
319         /* clear history so that no references to objects are held any more */
320
321         _history.clear ();
322
323         /* clear state tree so that no references to objects are held any more */
324
325         if (state_tree) {
326                 delete state_tree;
327         }
328
329         terminate_butler_thread ();
330         //terminate_midi_thread ();
331
332         if (click_data && click_data != default_click) {
333                 delete [] click_data;
334         }
335
336         if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
337                 delete [] click_emphasis_data;
338         }
339
340         clear_clicks ();
341
342         delete _scratch_buffers;
343         delete _silent_buffers;
344         delete _mix_buffers;
345
346         AudioDiskstream::free_working_buffers();
347
348         Route::SyncOrderKeys.clear();
349
350 #undef TRACK_DESTRUCTION
351 #ifdef TRACK_DESTRUCTION
352         cerr << "delete named selections\n";
353 #endif /* TRACK_DESTRUCTION */
354         for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
355                 NamedSelectionList::iterator tmp;
356
357                 tmp = i;
358                 ++tmp;
359
360                 delete *i;
361                 i = tmp;
362         }
363
364 #ifdef TRACK_DESTRUCTION
365         cerr << "delete playlists\n";
366 #endif /* TRACK_DESTRUCTION */
367         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
368                 PlaylistList::iterator tmp;
369
370                 tmp = i;
371                 ++tmp;
372
373                 (*i)->drop_references ();
374
375                 i = tmp;
376         }
377
378         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
379                 PlaylistList::iterator tmp;
380
381                 tmp = i;
382                 ++tmp;
383
384                 (*i)->drop_references ();
385
386                 i = tmp;
387         }
388
389         playlists.clear ();
390         unused_playlists.clear ();
391
392 #ifdef TRACK_DESTRUCTION
393         cerr << "delete regions\n";
394 #endif /* TRACK_DESTRUCTION */
395
396         for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
397                 RegionList::iterator tmp;
398
399                 tmp = i;
400                 ++tmp;
401
402                 i->second->drop_references ();
403
404                 i = tmp;
405         }
406
407         regions.clear ();
408
409 #ifdef TRACK_DESTRUCTION
410         cerr << "delete routes\n";
411 #endif /* TRACK_DESTRUCTION */
412         {
413                 RCUWriter<RouteList> writer (routes);
414                 boost::shared_ptr<RouteList> r = writer.get_copy ();
415                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
416                         (*i)->drop_references ();
417                 }
418                 r->clear ();
419                 /* writer goes out of scope and updates master */
420         }
421
422         routes.flush ();
423
424 #ifdef TRACK_DESTRUCTION
425         cerr << "delete diskstreams\n";
426 #endif /* TRACK_DESTRUCTION */
427        {
428                RCUWriter<DiskstreamList> dwriter (diskstreams);
429                boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
430                for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
431                        (*i)->drop_references ();
432                }
433                dsl->clear ();
434        }
435        diskstreams.flush ();
436
437 #ifdef TRACK_DESTRUCTION
438         cerr << "delete audio sources\n";
439 #endif /* TRACK_DESTRUCTION */
440         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
441                 SourceMap::iterator tmp;
442
443                 tmp = i;
444                 ++tmp;
445
446                 i->second->drop_references ();
447
448                 i = tmp;
449         }
450         sources.clear ();
451
452 #ifdef TRACK_DESTRUCTION
453         cerr << "delete mix groups\n";
454 #endif /* TRACK_DESTRUCTION */
455         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
456                 list<RouteGroup*>::iterator tmp;
457
458                 tmp = i;
459                 ++tmp;
460
461                 delete *i;
462
463                 i = tmp;
464         }
465
466 #ifdef TRACK_DESTRUCTION
467         cerr << "delete edit groups\n";
468 #endif /* TRACK_DESTRUCTION */
469         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
470                 list<RouteGroup*>::iterator tmp;
471
472                 tmp = i;
473                 ++tmp;
474
475                 delete *i;
476
477                 i = tmp;
478         }
479
480         if (butler_mixdown_buffer) {
481                 delete [] butler_mixdown_buffer;
482         }
483
484         if (butler_gain_buffer) {
485                 delete [] butler_gain_buffer;
486         }
487
488         Crossfade::set_buffer_size (0);
489
490         if (mmc) {
491                 delete mmc;
492         }
493 }
494
495 void
496 Session::set_worst_io_latencies ()
497 {
498         _worst_output_latency = 0;
499         _worst_input_latency = 0;
500
501         if (!_engine.connected()) {
502                 return;
503         }
504
505         boost::shared_ptr<RouteList> r = routes.reader ();
506
507         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
508                 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
509                 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
510         }
511 }
512
513 void
514 Session::when_engine_running ()
515 {
516         string first_physical_output;
517
518         /* we don't want to run execute this again */
519
520         BootMessage (_("Set block size and sample rate"));
521
522         set_block_size (_engine.frames_per_cycle());
523         set_frame_rate (_engine.frame_rate());
524
525         BootMessage (_("Using configuration"));
526
527         Config->map_parameters (mem_fun (*this, &Session::config_changed));
528
529         /* every time we reconnect, recompute worst case output latencies */
530
531         _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
532
533         if (synced_to_jack()) {
534                 _engine.transport_stop ();
535         }
536
537         if (Config->get_jack_time_master()) {
538                 _engine.transport_locate (_transport_frame);
539         }
540
541         _clicking = false;
542
543         try {
544                 XMLNode* child = 0;
545
546                 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
547
548                 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
549
550                         /* existing state for Click */
551
552                         if (_click_io->set_state (*child->children().front()) == 0) {
553
554                                 _clicking = Config->get_clicking ();
555
556                         } else {
557
558                                 error << _("could not setup Click I/O") << endmsg;
559                                 _clicking = false;
560                         }
561
562                 } else {
563
564                         /* default state for Click */
565
566                         first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
567
568                         if (first_physical_output.length()) {
569                                 if (_click_io->add_output_port (first_physical_output, this)) {
570                                         // relax, even though its an error
571                                 } else {
572                                         _clicking = Config->get_clicking ();
573                                 }
574                         }
575                 }
576         }
577
578         catch (failed_constructor& err) {
579                 error << _("cannot setup Click I/O") << endmsg;
580         }
581
582         BootMessage (_("Compute I/O Latencies"));
583
584         set_worst_io_latencies ();
585
586         if (_clicking) {
587                 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
588         }
589
590         /* Create a set of Bundle objects that map
591            to the physical outputs currently available
592         */
593
594         BootMessage (_("Set up standard connections"));
595
596         /* ONE: MONO */
597
598         for (uint32_t np = 0; np < n_physical_outputs; ++np) {
599                 char buf[32];
600                 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
601
602                 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
603                 c->set_channels (1);
604                 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
605
606                 add_bundle (c);
607         }
608
609         for (uint32_t np = 0; np < n_physical_inputs; ++np) {
610                 char buf[32];
611                 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
612
613                 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
614                 c->set_channels (1);
615                 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
616
617                 add_bundle (c);
618         }
619
620         /* TWO: STEREO */
621
622         for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
623                 char buf[32];
624                 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
625
626                 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
627                 c->set_channels (2);
628                 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
629                 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
630
631                 add_bundle (c);
632         }
633
634         for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
635                 char buf[32];
636                 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
637
638                 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
639                 c->set_channels (2);
640                 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
641                 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
642
643                 add_bundle (c);
644         }
645
646         /* THREE MASTER */
647
648         if (_master_out) {
649
650                 /* create master/control ports */
651
652                 if (_master_out) {
653                         uint32_t n;
654
655                         /* force the master to ignore any later call to this */
656
657                         if (_master_out->pending_state_node) {
658                                 _master_out->ports_became_legal();
659                         }
660
661                         /* no panner resets till we are through */
662
663                         _master_out->defer_pan_reset ();
664
665                         while (_master_out->n_inputs().n_audio()
666                                         < _master_out->input_maximum().n_audio()) {
667                                 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
668                                         error << _("cannot setup master inputs")
669                                               << endmsg;
670                                         break;
671                                 }
672                         }
673                         n = 0;
674                         while (_master_out->n_outputs().n_audio()
675                                         < _master_out->output_maximum().n_audio()) {
676                                 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
677                                         error << _("cannot setup master outputs")
678                                               << endmsg;
679                                         break;
680                                 }
681                                 n++;
682                         }
683
684                         _master_out->allow_pan_reset ();
685
686                 }
687
688                 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
689
690                 c->set_channels (_master_out->n_inputs().n_total());
691                 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
692                         c->set_port (n, _master_out->input(n)->name());
693                 }
694                 add_bundle (c);
695         }
696
697         BootMessage (_("Setup signal flow and plugins"));
698
699         hookup_io ();
700
701         /* catch up on send+insert cnts */
702
703         BootMessage (_("Catch up with send/insert state"));
704
705         insert_cnt = 0;
706
707         for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
708                 uint32_t id;
709
710                 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
711                         if (id > insert_cnt) {
712                                 insert_cnt = id;
713                         }
714                 }
715         }
716
717         send_cnt = 0;
718
719         for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
720                 uint32_t id;
721
722                 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
723                         if (id > send_cnt) {
724                                 send_cnt = id;
725                         }
726                 }
727         }
728
729
730         _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
731
732         /* hook us up to the engine */
733
734         BootMessage (_("Connect to engine"));
735
736         _engine.set_session (this);
737
738 #ifdef HAVE_LIBLO
739         /* and to OSC */
740
741         BootMessage (_("OSC startup"));
742
743         osc->set_session (*this);
744 #endif
745
746 }
747
748 void
749 Session::hookup_io ()
750 {
751         /* stop graph reordering notifications from
752            causing resorts, etc.
753         */
754
755         _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
756
757
758         if (auditioner == 0) {
759
760                 /* we delay creating the auditioner till now because
761                    it makes its own connections to ports.
762                    the engine has to be running for this to work.
763                 */
764
765                 try {
766                         auditioner.reset (new Auditioner (*this));
767                 }
768
769                 catch (failed_constructor& err) {
770                         warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
771                 }
772         }
773
774         /* Tell all IO objects to create their ports */
775
776         IO::enable_ports ();
777
778         if (_control_out) {
779                 uint32_t n;
780                 vector<string> cports;
781
782                 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
783                         if (_control_out->add_input_port ("", this)) {
784                                 error << _("cannot setup control inputs")
785                                       << endmsg;
786                                 break;
787                         }
788                 }
789                 n = 0;
790                 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
791                         if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
792                                 error << _("cannot set up master outputs")
793                                       << endmsg;
794                                 break;
795                         }
796                         n++;
797                 }
798
799
800                 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
801
802                 for (n = 0; n < ni; ++n) {
803                         cports.push_back (_control_out->input(n)->name());
804                 }
805
806                 boost::shared_ptr<RouteList> r = routes.reader ();
807
808                 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
809                         (*x)->set_control_outs (cports);
810                 }
811         }
812
813         /* load bundles, which we may have postponed earlier on */
814         if (_bundle_xml_node) {
815                 load_bundles (*_bundle_xml_node);
816                 delete _bundle_xml_node;
817         }
818
819         /* Tell all IO objects to connect themselves together */
820
821         IO::enable_connecting ();
822
823         /* Now reset all panners */
824
825         IO::reset_panners ();
826
827         /* Anyone who cares about input state, wake up and do something */
828
829         IOConnectionsComplete (); /* EMIT SIGNAL */
830
831         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
832
833
834         /* now handle the whole enchilada as if it was one
835            graph reorder event.
836         */
837
838         graph_reordered ();
839
840         /* update mixer solo state */
841
842         catch_up_on_solo();
843 }
844
845 void
846 Session::playlist_length_changed ()
847 {
848         /* we can't just increase end_location->end() if pl->get_maximum_extent()
849            if larger. if the playlist used to be the longest playlist,
850            and its now shorter, we have to decrease end_location->end(). hence,
851            we have to iterate over all diskstreams and check the
852            playlists currently in use.
853         */
854         find_current_end ();
855 }
856
857 void
858 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
859 {
860         boost::shared_ptr<Playlist> playlist;
861
862         if ((playlist = dstream->playlist()) != 0) {
863                 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
864         }
865
866         /* see comment in playlist_length_changed () */
867         find_current_end ();
868 }
869
870 bool
871 Session::record_enabling_legal () const
872 {
873         /* this used to be in here, but survey says.... we don't need to restrict it */
874         // if (record_status() == Recording) {
875         //      return false;
876         // }
877
878         if (Config->get_all_safe()) {
879                 return false;
880         }
881         return true;
882 }
883
884 void
885 Session::reset_input_monitor_state ()
886 {
887         if (transport_rolling()) {
888
889                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
890
891                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
892                         if ((*i)->record_enabled ()) {
893                                 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
894                                 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
895                         }
896                 }
897         } else {
898                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899
900                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
901                         if ((*i)->record_enabled ()) {
902                                 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
903                                 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
904                         }
905                 }
906         }
907 }
908
909 void
910 Session::auto_punch_start_changed (Location* location)
911 {
912         replace_event (Event::PunchIn, location->start());
913
914         if (get_record_enabled() && Config->get_punch_in()) {
915                 /* capture start has been changed, so save new pending state */
916                 save_state ("", true);
917         }
918 }
919
920 void
921 Session::auto_punch_end_changed (Location* location)
922 {
923         nframes_t when_to_stop = location->end();
924         // when_to_stop += _worst_output_latency + _worst_input_latency;
925         replace_event (Event::PunchOut, when_to_stop);
926 }
927
928 void
929 Session::auto_punch_changed (Location* location)
930 {
931         nframes_t when_to_stop = location->end();
932
933         replace_event (Event::PunchIn, location->start());
934         //when_to_stop += _worst_output_latency + _worst_input_latency;
935         replace_event (Event::PunchOut, when_to_stop);
936 }
937
938 void
939 Session::auto_loop_changed (Location* location)
940 {
941         replace_event (Event::AutoLoop, location->end(), location->start());
942
943         if (transport_rolling() && play_loop) {
944
945                 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
946
947                 if (_transport_frame > location->end()) {
948                         // relocate to beginning of loop
949                         clear_events (Event::LocateRoll);
950
951                         request_locate (location->start(), true);
952
953                 }
954                 else if (Config->get_seamless_loop() && !loop_changing) {
955
956                         // schedule a locate-roll to refill the diskstreams at the
957                         // previous loop end
958                         loop_changing = true;
959
960                         if (location->end() > last_loopend) {
961                                 clear_events (Event::LocateRoll);
962                                 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
963                                 queue_event (ev);
964                         }
965
966                 }
967         }
968
969         last_loopend = location->end();
970 }
971
972 void
973 Session::set_auto_punch_location (Location* location)
974 {
975         Location* existing;
976
977         if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
978                 auto_punch_start_changed_connection.disconnect();
979                 auto_punch_end_changed_connection.disconnect();
980                 auto_punch_changed_connection.disconnect();
981                 existing->set_auto_punch (false, this);
982                 remove_event (existing->start(), Event::PunchIn);
983                 clear_events (Event::PunchOut);
984                 auto_punch_location_changed (0);
985         }
986
987         set_dirty();
988
989         if (location == 0) {
990                 return;
991         }
992
993         if (location->end() <= location->start()) {
994                 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
995                 return;
996         }
997
998         auto_punch_start_changed_connection.disconnect();
999         auto_punch_end_changed_connection.disconnect();
1000         auto_punch_changed_connection.disconnect();
1001
1002         auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1003         auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1004         auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1005
1006         location->set_auto_punch (true, this);
1007
1008
1009         auto_punch_changed (location);
1010
1011         auto_punch_location_changed (location);
1012 }
1013
1014 void
1015 Session::set_auto_loop_location (Location* location)
1016 {
1017         Location* existing;
1018
1019         if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1020                 auto_loop_start_changed_connection.disconnect();
1021                 auto_loop_end_changed_connection.disconnect();
1022                 auto_loop_changed_connection.disconnect();
1023                 existing->set_auto_loop (false, this);
1024                 remove_event (existing->end(), Event::AutoLoop);
1025                 auto_loop_location_changed (0);
1026         }
1027
1028         set_dirty();
1029
1030         if (location == 0) {
1031                 return;
1032         }
1033
1034         if (location->end() <= location->start()) {
1035                 error << _("Session: you can't use a mark for auto loop") << endmsg;
1036                 return;
1037         }
1038
1039         last_loopend = location->end();
1040
1041         auto_loop_start_changed_connection.disconnect();
1042         auto_loop_end_changed_connection.disconnect();
1043         auto_loop_changed_connection.disconnect();
1044
1045         auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1046         auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1047         auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1048
1049         location->set_auto_loop (true, this);
1050
1051         /* take care of our stuff first */
1052
1053         auto_loop_changed (location);
1054
1055         /* now tell everyone else */
1056
1057         auto_loop_location_changed (location);
1058 }
1059
1060 void
1061 Session::locations_added (Location* ignored)
1062 {
1063         set_dirty ();
1064 }
1065
1066 void
1067 Session::locations_changed ()
1068 {
1069         _locations.apply (*this, &Session::handle_locations_changed);
1070 }
1071
1072 void
1073 Session::handle_locations_changed (Locations::LocationList& locations)
1074 {
1075         Locations::LocationList::iterator i;
1076         Location* location;
1077         bool set_loop = false;
1078         bool set_punch = false;
1079
1080         for (i = locations.begin(); i != locations.end(); ++i) {
1081
1082                 location =* i;
1083
1084                 if (location->is_auto_punch()) {
1085                         set_auto_punch_location (location);
1086                         set_punch = true;
1087                 }
1088                 if (location->is_auto_loop()) {
1089                         set_auto_loop_location (location);
1090                         set_loop = true;
1091                 }
1092
1093                 if (location->is_start()) {
1094                         start_location = location;
1095                 }
1096                 if (location->is_end()) {
1097                         end_location = location;
1098                 }
1099         }
1100
1101         if (!set_loop) {
1102                 set_auto_loop_location (0);
1103         }
1104         if (!set_punch) {
1105                 set_auto_punch_location (0);
1106         }
1107
1108         set_dirty();
1109 }
1110
1111 void
1112 Session::enable_record ()
1113 {
1114         /* XXX really atomic compare+swap here */
1115         if (g_atomic_int_get (&_record_status) != Recording) {
1116                 g_atomic_int_set (&_record_status, Recording);
1117                 _last_record_location = _transport_frame;
1118                 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1119
1120                 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1121                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1122                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1123                                 if ((*i)->record_enabled ()) {
1124                                         (*i)->monitor_input (true);
1125                                 }
1126                         }
1127                 }
1128
1129                 RecordStateChanged ();
1130         }
1131 }
1132
1133 void
1134 Session::disable_record (bool rt_context, bool force)
1135 {
1136         RecordState rs;
1137
1138         if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1139
1140                 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1141                         g_atomic_int_set (&_record_status, Disabled);
1142                 } else {
1143                         if (rs == Recording) {
1144                                 g_atomic_int_set (&_record_status, Enabled);
1145                         }
1146                 }
1147
1148                 // FIXME: timestamp correct? [DR]
1149                 // FIXME FIXME FIXME: rt_context?  this must be called in the process thread.
1150                 // does this /need/ to be sent in all cases?
1151                 if (rt_context)
1152                         deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1153
1154                 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1155                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1156
1157                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1158                                 if ((*i)->record_enabled ()) {
1159                                         (*i)->monitor_input (false);
1160                                 }
1161                         }
1162                 }
1163
1164                 RecordStateChanged (); /* emit signal */
1165
1166                 if (!rt_context) {
1167                         remove_pending_capture_state ();
1168                 }
1169         }
1170 }
1171
1172 void
1173 Session::step_back_from_record ()
1174 {
1175         /* XXX really atomic compare+swap here */
1176         if (g_atomic_int_get (&_record_status) == Recording) {
1177                 g_atomic_int_set (&_record_status, Enabled);
1178
1179                 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1180                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1181
1182                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1183                                 if ((*i)->record_enabled ()) {
1184                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1185                                         (*i)->monitor_input (false);
1186                                 }
1187                         }
1188                 }
1189         }
1190 }
1191
1192 void
1193 Session::maybe_enable_record ()
1194 {
1195         g_atomic_int_set (&_record_status, Enabled);
1196
1197         /* this function is currently called from somewhere other than an RT thread.
1198            this save_state() call therefore doesn't impact anything.
1199         */
1200
1201         save_state ("", true);
1202
1203         if (_transport_speed) {
1204                 if (!Config->get_punch_in()) {
1205                         enable_record ();
1206                 }
1207         } else {
1208                 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1209                 RecordStateChanged (); /* EMIT SIGNAL */
1210         }
1211
1212         set_dirty();
1213 }
1214
1215 nframes_t
1216 Session::audible_frame () const
1217 {
1218         nframes_t ret;
1219         nframes_t offset;
1220         nframes_t tf;
1221
1222         /* the first of these two possible settings for "offset"
1223            mean that the audible frame is stationary until
1224            audio emerges from the latency compensation
1225            "pseudo-pipeline".
1226
1227            the second means that the audible frame is stationary
1228            until audio would emerge from a physical port
1229            in the absence of any plugin latency compensation
1230         */
1231
1232         offset = _worst_output_latency;
1233
1234         if (offset > current_block_size) {
1235                 offset -= current_block_size;
1236         } else {
1237                 /* XXX is this correct? if we have no external
1238                    physical connections and everything is internal
1239                    then surely this is zero? still, how
1240                    likely is that anyway?
1241                 */
1242                 offset = current_block_size;
1243         }
1244
1245         if (synced_to_jack()) {
1246                 tf = _engine.transport_frame();
1247         } else {
1248                 tf = _transport_frame;
1249         }
1250
1251         if (_transport_speed == 0) {
1252                 return tf;
1253         }
1254
1255         if (tf < offset) {
1256                 return 0;
1257         }
1258
1259         ret = tf;
1260
1261         if (!non_realtime_work_pending()) {
1262
1263                 /* MOVING */
1264
1265                 /* take latency into account */
1266
1267                 ret -= offset;
1268         }
1269
1270         return ret;
1271 }
1272
1273 void
1274 Session::set_frame_rate (nframes_t frames_per_second)
1275 {
1276         /** \fn void Session::set_frame_size(nframes_t)
1277                 the AudioEngine object that calls this guarantees
1278                 that it will not be called while we are also in
1279                 ::process(). Its fine to do things that block
1280                 here.
1281         */
1282
1283         _base_frame_rate = frames_per_second;
1284
1285         sync_time_vars();
1286
1287         Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1288
1289         clear_clicks ();
1290
1291         // XXX we need some equivalent to this, somehow
1292         // SndFileSource::setup_standard_crossfades (frames_per_second);
1293
1294         set_dirty();
1295
1296         /* XXX need to reset/reinstantiate all LADSPA plugins */
1297 }
1298
1299 void
1300 Session::set_block_size (nframes_t nframes)
1301 {
1302         /* the AudioEngine guarantees
1303            that it will not be called while we are also in
1304            ::process(). It is therefore fine to do things that block
1305            here.
1306         */
1307
1308         {
1309
1310                 current_block_size = nframes;
1311
1312                 ensure_buffers(_scratch_buffers->available());
1313
1314                 if (_gain_automation_buffer) {
1315                         delete [] _gain_automation_buffer;
1316                 }
1317                 _gain_automation_buffer = new gain_t[nframes];
1318
1319                 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1320
1321                 boost::shared_ptr<RouteList> r = routes.reader ();
1322
1323                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1324                         (*i)->set_block_size (nframes);
1325                 }
1326
1327                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1328                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1329                         (*i)->set_block_size (nframes);
1330                 }
1331
1332                 set_worst_io_latencies ();
1333         }
1334 }
1335
1336 void
1337 Session::set_default_fade (float steepness, float fade_msecs)
1338 {
1339 #if 0
1340         nframes_t fade_frames;
1341
1342         /* Don't allow fade of less 1 frame */
1343
1344         if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1345
1346                 fade_msecs = 0;
1347                 fade_frames = 0;
1348
1349         } else {
1350
1351                 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1352
1353         }
1354
1355         default_fade_msecs = fade_msecs;
1356         default_fade_steepness = steepness;
1357
1358         {
1359                 // jlc, WTF is this!
1360                 Glib::RWLock::ReaderLock lm (route_lock);
1361                 AudioRegion::set_default_fade (steepness, fade_frames);
1362         }
1363
1364         set_dirty();
1365
1366         /* XXX have to do this at some point */
1367         /* foreach region using default fade, reset, then
1368            refill_all_diskstream_buffers ();
1369         */
1370 #endif
1371 }
1372
1373 struct RouteSorter {
1374     bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1375             if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1376                     return false;
1377             } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1378                     return true;
1379             } else {
1380                     if (r1->fed_by.empty()) {
1381                             if (r2->fed_by.empty()) {
1382                                     /* no ardour-based connections inbound to either route. just use signal order */
1383                                     return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1384                             } else {
1385                                     /* r2 has connections, r1 does not; run r1 early */
1386                                     return true;
1387                             }
1388                     } else {
1389                             return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390                     }
1391             }
1392     }
1393 };
1394
1395 static void
1396 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1397 {
1398         shared_ptr<Route> r2;
1399
1400         if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1401                 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1402                 return;
1403         }
1404
1405         /* make a copy of the existing list of routes that feed r1 */
1406
1407         set<shared_ptr<Route> > existing = r1->fed_by;
1408
1409         /* for each route that feeds r1, recurse, marking it as feeding
1410            rbase as well.
1411         */
1412
1413         for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1414                 r2 =* i;
1415
1416                 /* r2 is a route that feeds r1 which somehow feeds base. mark
1417                    base as being fed by r2
1418                 */
1419
1420                 rbase->fed_by.insert (r2);
1421
1422                 if (r2 != rbase) {
1423
1424                         /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1425                            stop here.
1426                          */
1427
1428                         if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1429                                 continue;
1430                         }
1431
1432                         /* now recurse, so that we can mark base as being fed by
1433                            all routes that feed r2
1434                         */
1435
1436                         trace_terminal (r2, rbase);
1437                 }
1438
1439         }
1440 }
1441
1442 void
1443 Session::resort_routes ()
1444 {
1445         /* don't do anything here with signals emitted
1446            by Routes while we are being destroyed.
1447         */
1448
1449         if (_state_of_the_state & Deletion) {
1450                 return;
1451         }
1452
1453
1454         {
1455
1456                 RCUWriter<RouteList> writer (routes);
1457                 shared_ptr<RouteList> r = writer.get_copy ();
1458                 resort_routes_using (r);
1459                 /* writer goes out of scope and forces update */
1460         }
1461
1462 }
1463 void
1464 Session::resort_routes_using (shared_ptr<RouteList> r)
1465 {
1466         RouteList::iterator i, j;
1467
1468         for (i = r->begin(); i != r->end(); ++i) {
1469
1470                 (*i)->fed_by.clear ();
1471
1472                 for (j = r->begin(); j != r->end(); ++j) {
1473
1474                         /* although routes can feed themselves, it will
1475                            cause an endless recursive descent if we
1476                            detect it. so don't bother checking for
1477                            self-feeding.
1478                         */
1479
1480                         if (*j == *i) {
1481                                 continue;
1482                         }
1483
1484                         if ((*j)->feeds (*i)) {
1485                                 (*i)->fed_by.insert (*j);
1486                         }
1487                 }
1488         }
1489
1490         for (i = r->begin(); i != r->end(); ++i) {
1491                 trace_terminal (*i, *i);
1492         }
1493
1494         RouteSorter cmp;
1495         r->sort (cmp);
1496
1497 #if 0
1498         cerr << "finished route resort\n";
1499
1500         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501                 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1502         }
1503         cerr << endl;
1504 #endif
1505
1506 }
1507
1508 list<boost::shared_ptr<MidiTrack> >
1509 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1510 {
1511         char track_name[32];
1512         uint32_t track_id = 0;
1513         uint32_t n = 0;
1514         string port;
1515         RouteList new_routes;
1516         list<boost::shared_ptr<MidiTrack> > ret;
1517         //uint32_t control_id;
1518
1519         // FIXME: need physical I/O and autoconnect stuff for MIDI
1520
1521         /* count existing midi tracks */
1522
1523         {
1524                 shared_ptr<RouteList> r = routes.reader ();
1525
1526                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1527                         if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1528                                 if (!(*i)->is_hidden()) {
1529                                         n++;
1530                                         //channels_used += (*i)->n_inputs().n_midi();
1531                                 }
1532                         }
1533                 }
1534         }
1535
1536 #if 0   
1537         vector<string> physinputs;
1538         vector<string> physoutputs;
1539
1540         _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1541         _engine.get_physical_inputs (DataType::MIDI, physinputs);
1542         uint32_t nphysical_in;
1543         uint32_t nphysical_out;
1544         control_id = ntracks() + nbusses();
1545 #endif
1546
1547         while (how_many) {
1548
1549                 /* check for duplicate route names, since we might have pre-existing
1550                    routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1551                    save, close,restart,add new route - first named route is now
1552                    Audio2)
1553                 */
1554
1555
1556                 do {
1557                         ++track_id;
1558
1559                         snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1560
1561                         if (route_by_name (track_name) == 0) {
1562                                 break;
1563                         }
1564
1565                 } while (track_id < (UINT_MAX-1));
1566
1567                 /*
1568                   if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1569                         nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1570                 } else {
1571                         nphysical_in = 0;
1572                 }
1573
1574                 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1575                         nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1576                 } else {
1577                         nphysical_out = 0;
1578                 }
1579                 */
1580
1581                 shared_ptr<MidiTrack> track;
1582
1583                 try {
1584                         track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1585
1586                         if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1587                                 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1588                                 goto failed;
1589                         }
1590
1591                         /*
1592                         if (nphysical_in) {
1593                                 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1594
1595                                         port = "";
1596
1597                                         if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1598                                                 port = physinputs[(channels_used+x)%nphysical_in];
1599                                         }
1600
1601                                         if (port.length() && track->connect_input (track->input (x), port, this)) {
1602                                                 break;
1603                                         }
1604                                 }
1605                         }
1606
1607                         for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1608
1609                                 port = "";
1610
1611                                 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1612                                         port = physoutputs[(channels_used+x)%nphysical_out];
1613                                 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1614                                         if (_master_out) {
1615                                                 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1616                                         }
1617                                 }
1618
1619                                 if (port.length() && track->connect_output (track->output (x), port, this)) {
1620                                         break;
1621                                 }
1622                         }
1623
1624                         channels_used += track->n_inputs ().n_midi();
1625
1626                         */
1627
1628                         track->midi_diskstream()->non_realtime_input_change();
1629
1630                         track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1631                         //track->set_remote_control_id (control_id);
1632
1633                         new_routes.push_back (track);
1634                         ret.push_back (track);
1635                 }
1636
1637                 catch (failed_constructor &err) {
1638                         error << _("Session: could not create new midi track.") << endmsg;
1639
1640                         if (track) {
1641                                 /* we need to get rid of this, since the track failed to be created */
1642                                 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1643
1644                                 {
1645                                         RCUWriter<DiskstreamList> writer (diskstreams);
1646                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1647                                         ds->remove (track->midi_diskstream());
1648                                 }
1649                         }
1650
1651                         goto failed;
1652                 }
1653
1654                 catch (AudioEngine::PortRegistrationFailure& pfe) {
1655
1656                         error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1657
1658                         if (track) {
1659                                 /* we need to get rid of this, since the track failed to be created */
1660                                 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1661
1662                                 {
1663                                         RCUWriter<DiskstreamList> writer (diskstreams);
1664                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1665                                         ds->remove (track->midi_diskstream());
1666                                 }
1667                         }
1668
1669                         goto failed;
1670                 }
1671
1672                 --how_many;
1673         }
1674
1675   failed:
1676         if (!new_routes.empty()) {
1677                 add_routes (new_routes, false);
1678                 save_state (_current_snapshot_name);
1679         }
1680
1681         return ret;
1682 }
1683
1684 list<boost::shared_ptr<AudioTrack> >
1685 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1686 {
1687         char track_name[32];
1688         uint32_t track_id = 0;
1689         uint32_t n = 0;
1690         uint32_t channels_used = 0;
1691         string port;
1692         RouteList new_routes;
1693         list<boost::shared_ptr<AudioTrack> > ret;
1694         uint32_t control_id;
1695
1696         /* count existing audio tracks */
1697
1698         {
1699                 shared_ptr<RouteList> r = routes.reader ();
1700
1701                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1702                         if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1703                                 if (!(*i)->is_hidden()) {
1704                                         n++;
1705                                         channels_used += (*i)->n_inputs().n_audio();
1706                                 }
1707                         }
1708                 }
1709         }
1710
1711         vector<string> physinputs;
1712         vector<string> physoutputs;
1713         uint32_t nphysical_in;
1714         uint32_t nphysical_out;
1715
1716         _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1717         _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1718         control_id = ntracks() + nbusses() + 1;
1719
1720         while (how_many) {
1721
1722                 /* check for duplicate route names, since we might have pre-existing
1723                    routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1724                    save, close,restart,add new route - first named route is now
1725                    Audio2)
1726                 */
1727
1728
1729                 do {
1730                         ++track_id;
1731
1732                         snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1733
1734                         if (route_by_name (track_name) == 0) {
1735                                 break;
1736                         }
1737
1738                 } while (track_id < (UINT_MAX-1));
1739
1740                 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1741                         nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1742                 } else {
1743                         nphysical_in = 0;
1744                 }
1745
1746                 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1747                         nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1748                 } else {
1749                         nphysical_out = 0;
1750                 }
1751
1752                 shared_ptr<AudioTrack> track;
1753
1754                 try {
1755                         track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1756
1757                         if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1758                                 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1759                                                          input_channels, output_channels)
1760                                       << endmsg;
1761                                 goto failed;
1762                         }
1763
1764                         if (nphysical_in) {
1765                                 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1766
1767                                         port = "";
1768
1769                                         if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1770                                                 port = physinputs[(channels_used+x)%nphysical_in];
1771                                         }
1772
1773                                         if (port.length() && track->connect_input (track->input (x), port, this)) {
1774                                                 break;
1775                                         }
1776                                 }
1777                         }
1778
1779                         for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1780
1781                                 port = "";
1782
1783                                 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1784                                         port = physoutputs[(channels_used+x)%nphysical_out];
1785                                 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1786                                         if (_master_out) {
1787                                                 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1788                                         }
1789                                 }
1790
1791                                 if (port.length() && track->connect_output (track->output (x), port, this)) {
1792                                         break;
1793                                 }
1794                         }
1795
1796                         channels_used += track->n_inputs ().n_audio();
1797
1798                         track->audio_diskstream()->non_realtime_input_change();
1799
1800                         track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1801                         track->set_remote_control_id (control_id);
1802                         ++control_id;
1803
1804                         new_routes.push_back (track);
1805                         ret.push_back (track);
1806                 }
1807
1808                 catch (failed_constructor &err) {
1809                         error << _("Session: could not create new audio track.") << endmsg;
1810
1811                         if (track) {
1812                                 /* we need to get rid of this, since the track failed to be created */
1813                                 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1814
1815                                 {
1816                                         RCUWriter<DiskstreamList> writer (diskstreams);
1817                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1818                                         ds->remove (track->audio_diskstream());
1819                                 }
1820                         }
1821
1822                         goto failed;
1823                 }
1824
1825                 catch (AudioEngine::PortRegistrationFailure& pfe) {
1826
1827                         error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1828
1829                         if (track) {
1830                                 /* we need to get rid of this, since the track failed to be created */
1831                                 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1832
1833                                 {
1834                                         RCUWriter<DiskstreamList> writer (diskstreams);
1835                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1836                                         ds->remove (track->audio_diskstream());
1837                                 }
1838                         }
1839
1840                         goto failed;
1841                 }
1842
1843                 --how_many;
1844         }
1845
1846   failed:
1847         if (!new_routes.empty()) {
1848                 add_routes (new_routes, true);
1849         }
1850
1851         return ret;
1852 }
1853
1854 void
1855 Session::set_remote_control_ids ()
1856 {
1857         RemoteModel m = Config->get_remote_model();
1858
1859         shared_ptr<RouteList> r = routes.reader ();
1860
1861         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1862                 if ( MixerOrdered == m) {
1863                         long order = (*i)->order_key(N_("signal"));
1864                         (*i)->set_remote_control_id( order+1 );
1865                 } else if ( EditorOrdered == m) {
1866                         long order = (*i)->order_key(N_("editor"));
1867                         (*i)->set_remote_control_id( order+1 );
1868                 } else if ( UserOrdered == m) {
1869                         //do nothing ... only changes to remote id's are initiated by user
1870                 }
1871         }
1872 }
1873
1874
1875 Session::RouteList
1876 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1877 {
1878         char bus_name[32];
1879         uint32_t bus_id = 1;
1880         uint32_t n = 0;
1881         string port;
1882         RouteList ret;
1883         uint32_t control_id;
1884
1885         /* count existing audio busses */
1886
1887         {
1888                 shared_ptr<RouteList> r = routes.reader ();
1889
1890                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1891                         if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1892                                 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1893                                         bus_id++;
1894                                 }
1895                         }
1896                 }
1897         }
1898
1899         vector<string> physinputs;
1900         vector<string> physoutputs;
1901
1902         _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1903         _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1904         control_id = ntracks() + nbusses() + 1;
1905
1906         while (how_many) {
1907
1908                 do {
1909                         snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1910
1911                         bus_id++;
1912
1913                         if (route_by_name (bus_name) == 0) {
1914                                 break;
1915                         }
1916
1917                 } while (bus_id < (UINT_MAX-1));
1918
1919                 try {
1920                         shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1921
1922                         if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1923                                 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1924                                                          input_channels, output_channels)
1925                                       << endmsg;
1926                                 goto failure;
1927                         }
1928
1929                         for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1930
1931                                 port = "";
1932
1933                                 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1934                                                 port = physinputs[((n+x)%n_physical_inputs)];
1935                                 }
1936
1937                                 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1938                                         break;
1939                                 }
1940                         }
1941
1942                         for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1943
1944                                 port = "";
1945
1946                                 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1947                                         port = physoutputs[((n+x)%n_physical_outputs)];
1948                                 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1949                                         if (_master_out) {
1950                                                 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1951                                         }
1952                                 }
1953
1954                                 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1955                                         break;
1956                                 }
1957                         }
1958
1959                         bus->set_remote_control_id (control_id);
1960                         ++control_id;
1961
1962                         ret.push_back (bus);
1963                 }
1964
1965
1966                 catch (failed_constructor &err) {
1967                         error << _("Session: could not create new audio route.") << endmsg;
1968                         goto failure;
1969                 }
1970
1971                 catch (AudioEngine::PortRegistrationFailure& pfe) {
1972                         error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1973                         goto failure;
1974                 }
1975
1976
1977                 --how_many;
1978         }
1979
1980   failure:
1981         if (!ret.empty()) {
1982                 add_routes (ret, true);
1983         }
1984
1985         return ret;
1986
1987 }
1988
1989 void
1990 Session::add_routes (RouteList& new_routes, bool save)
1991 {
1992         {
1993                 RCUWriter<RouteList> writer (routes);
1994                 shared_ptr<RouteList> r = writer.get_copy ();
1995                 r->insert (r->end(), new_routes.begin(), new_routes.end());
1996                 resort_routes_using (r);
1997         }
1998
1999         for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2000
2001                 boost::weak_ptr<Route> wpr (*x);
2002
2003                 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2004                 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2005                 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2006                 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2007
2008                 if ((*x)->is_master()) {
2009                         _master_out = (*x);
2010                 }
2011
2012                 if ((*x)->is_control()) {
2013                         _control_out = (*x);
2014                 }
2015
2016                 add_bundle ((*x)->bundle_for_inputs());
2017                 add_bundle ((*x)->bundle_for_outputs());
2018         }
2019
2020         if (_control_out && IO::connecting_legal) {
2021
2022                 vector<string> cports;
2023                 uint32_t ni = _control_out->n_inputs().n_audio();
2024
2025                 for (uint32_t n = 0; n < ni; ++n) {
2026                         cports.push_back (_control_out->input(n)->name());
2027                 }
2028
2029                 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2030                         (*x)->set_control_outs (cports);
2031                 }
2032         }
2033
2034         set_dirty();
2035
2036         if (save) {
2037                 save_state (_current_snapshot_name);
2038         }
2039
2040         RouteAdded (new_routes); /* EMIT SIGNAL */
2041 }
2042
2043 void
2044 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2045 {
2046         /* need to do this in case we're rolling at the time, to prevent false underruns */
2047         dstream->do_refill_with_alloc ();
2048
2049         dstream->set_block_size (current_block_size);
2050
2051         {
2052                 RCUWriter<DiskstreamList> writer (diskstreams);
2053                 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2054                 ds->push_back (dstream);
2055                 /* writer goes out of scope, copies ds back to main */
2056         }
2057
2058         dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2059         /* this will connect to future changes, and check the current length */
2060         diskstream_playlist_changed (dstream);
2061
2062         dstream->prepare ();
2063
2064 }
2065
2066 void
2067 Session::remove_route (shared_ptr<Route> route)
2068 {
2069         {
2070                 RCUWriter<RouteList> writer (routes);
2071                 shared_ptr<RouteList> rs = writer.get_copy ();
2072
2073                 rs->remove (route);
2074
2075                 /* deleting the master out seems like a dumb
2076                    idea, but its more of a UI policy issue
2077                    than our concern.
2078                 */
2079
2080                 if (route == _master_out) {
2081                         _master_out = shared_ptr<Route> ();
2082                 }
2083
2084                 if (route == _control_out) {
2085                         _control_out = shared_ptr<Route> ();
2086
2087                         /* cancel control outs for all routes */
2088
2089                         vector<string> empty;
2090
2091                         for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2092                                 (*r)->set_control_outs (empty);
2093                         }
2094                 }
2095
2096                 update_route_solo_state ();
2097
2098                 /* writer goes out of scope, forces route list update */
2099         }
2100
2101         Track* t;
2102         boost::shared_ptr<Diskstream> ds;
2103
2104         if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2105                 ds = t->diskstream();
2106         }
2107
2108         if (ds) {
2109
2110                 {
2111                         RCUWriter<DiskstreamList> dsl (diskstreams);
2112                         boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2113                         d->remove (ds);
2114                 }
2115         }
2116
2117         find_current_end ();
2118
2119         // We need to disconnect the routes inputs and outputs
2120
2121         route->disconnect_inputs (0);
2122         route->disconnect_outputs (0);
2123
2124         update_latency_compensation (false, false);
2125         set_dirty();
2126
2127         /* get rid of it from the dead wood collection in the route list manager */
2128
2129         /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2130
2131         routes.flush ();
2132
2133         /* try to cause everyone to drop their references */
2134
2135         route->drop_references ();
2136
2137         /* save the new state of the world */
2138
2139         if (save_state (_current_snapshot_name)) {
2140                 save_history (_current_snapshot_name);
2141         }
2142 }
2143
2144 void
2145 Session::route_mute_changed (void* src)
2146 {
2147         set_dirty ();
2148 }
2149
2150 void
2151 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2152 {
2153         if (solo_update_disabled) {
2154                 // We know already
2155                 return;
2156         }
2157
2158         bool is_track;
2159         boost::shared_ptr<Route> route = wpr.lock ();
2160
2161         if (!route) {
2162                 /* should not happen */
2163                 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2164                 return;
2165         }
2166
2167         is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2168
2169         shared_ptr<RouteList> r = routes.reader ();
2170
2171         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2172
2173                 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2174
2175                 if (is_track) {
2176
2177                         /* don't mess with busses */
2178
2179                         if (dynamic_cast<Track*>((*i).get()) == 0) {
2180                                 continue;
2181                         }
2182
2183                 } else {
2184
2185                         /* don't mess with tracks */
2186
2187                         if (dynamic_cast<Track*>((*i).get()) != 0) {
2188                                 continue;
2189                         }
2190                 }
2191
2192                 if ((*i) != route &&
2193                     ((*i)->mix_group () == 0 ||
2194                      (*i)->mix_group () != route->mix_group () ||
2195                      !route->mix_group ()->is_active())) {
2196
2197                         if ((*i)->soloed()) {
2198
2199                                 /* if its already soloed, and solo latching is enabled,
2200                                    then leave it as it is.
2201                                 */
2202
2203                                 if (Config->get_solo_latched()) {
2204                                         continue;
2205                                 }
2206                         }
2207
2208                         /* do it */
2209
2210                         solo_update_disabled = true;
2211                         (*i)->set_solo (false, src);
2212                         solo_update_disabled = false;
2213                 }
2214         }
2215
2216         bool something_soloed = false;
2217         bool same_thing_soloed = false;
2218         bool signal = false;
2219
2220         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2221                 if ((*i)->soloed()) {
2222                         something_soloed = true;
2223                         if (dynamic_cast<Track*>((*i).get())) {
2224                                 if (is_track) {
2225                                         same_thing_soloed = true;
2226                                         break;
2227                                 }
2228                         } else {
2229                                 if (!is_track) {
2230                                         same_thing_soloed = true;
2231                                         break;
2232                                 }
2233                         }
2234                         break;
2235                 }
2236         }
2237
2238         if (something_soloed != currently_soloing) {
2239                 signal = true;
2240                 currently_soloing = something_soloed;
2241         }
2242
2243         modify_solo_mute (is_track, same_thing_soloed);
2244
2245         if (signal) {
2246                 SoloActive (currently_soloing); /* EMIT SIGNAL */
2247         }
2248
2249         SoloChanged (); /* EMIT SIGNAL */
2250
2251         set_dirty();
2252 }
2253
2254 void
2255 Session::update_route_solo_state ()
2256 {
2257         bool mute = false;
2258         bool is_track = false;
2259         bool signal = false;
2260
2261         /* caller must hold RouteLock */
2262
2263         /* this is where we actually implement solo by changing
2264            the solo mute setting of each track.
2265         */
2266
2267         shared_ptr<RouteList> r = routes.reader ();
2268
2269         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2270                 if ((*i)->soloed()) {
2271                         mute = true;
2272                         if (dynamic_cast<Track*>((*i).get())) {
2273                                 is_track = true;
2274                         }
2275                         break;
2276                 }
2277         }
2278
2279         if (mute != currently_soloing) {
2280                 signal = true;
2281                 currently_soloing = mute;
2282         }
2283
2284         if (!is_track && !mute) {
2285
2286                 /* nothing is soloed */
2287
2288                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289                         (*i)->set_solo_mute (false);
2290                 }
2291
2292                 if (signal) {
2293                         SoloActive (false);
2294                 }
2295
2296                 return;
2297         }
2298
2299         modify_solo_mute (is_track, mute);
2300
2301         if (signal) {
2302                 SoloActive (currently_soloing);
2303         }
2304 }
2305
2306 void
2307 Session::modify_solo_mute (bool is_track, bool mute)
2308 {
2309         shared_ptr<RouteList> r = routes.reader ();
2310
2311         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2312
2313                 if (is_track) {
2314
2315                         /* only alter track solo mute */
2316
2317                         if (dynamic_cast<Track*>((*i).get())) {
2318                                 if ((*i)->soloed()) {
2319                                         (*i)->set_solo_mute (!mute);
2320                                 } else {
2321                                         (*i)->set_solo_mute (mute);
2322                                 }
2323                         }
2324
2325                 } else {
2326
2327                         /* only alter bus solo mute */
2328
2329                         if (!dynamic_cast<Track*>((*i).get())) {
2330
2331                                 if ((*i)->soloed()) {
2332
2333                                         (*i)->set_solo_mute (false);
2334
2335                                 } else {
2336
2337                                         /* don't mute master or control outs
2338                                            in response to another bus solo
2339                                         */
2340
2341                                         if ((*i) != _master_out &&
2342                                             (*i) != _control_out) {
2343                                                 (*i)->set_solo_mute (mute);
2344                                         }
2345                                 }
2346                         }
2347
2348                 }
2349         }
2350 }
2351
2352
2353 void
2354 Session::catch_up_on_solo ()
2355 {
2356         /* this is called after set_state() to catch the full solo
2357            state, which can't be correctly determined on a per-route
2358            basis, but needs the global overview that only the session
2359            has.
2360         */
2361         update_route_solo_state();
2362 }
2363
2364 shared_ptr<Route>
2365 Session::route_by_name (string name)
2366 {
2367         shared_ptr<RouteList> r = routes.reader ();
2368
2369         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2370                 if ((*i)->name() == name) {
2371                         return *i;
2372                 }
2373         }
2374
2375         return shared_ptr<Route> ((Route*) 0);
2376 }
2377
2378 shared_ptr<Route>
2379 Session::route_by_id (PBD::ID id)
2380 {
2381         shared_ptr<RouteList> r = routes.reader ();
2382
2383         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2384                 if ((*i)->id() == id) {
2385                         return *i;
2386                 }
2387         }
2388
2389         return shared_ptr<Route> ((Route*) 0);
2390 }
2391
2392 shared_ptr<Route>
2393 Session::route_by_remote_id (uint32_t id)
2394 {
2395         shared_ptr<RouteList> r = routes.reader ();
2396
2397         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2398                 if ((*i)->remote_control_id() == id) {
2399                         return *i;
2400                 }
2401         }
2402
2403         return shared_ptr<Route> ((Route*) 0);
2404 }
2405
2406 void
2407 Session::find_current_end ()
2408 {
2409         if (_state_of_the_state & Loading) {
2410                 return;
2411         }
2412
2413         nframes_t max = get_maximum_extent ();
2414
2415         if (max > end_location->end()) {
2416                 end_location->set_end (max);
2417                 set_dirty();
2418                 DurationChanged(); /* EMIT SIGNAL */
2419         }
2420 }
2421
2422 nframes_t
2423 Session::get_maximum_extent () const
2424 {
2425         nframes_t max = 0;
2426         nframes_t me;
2427
2428         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2429
2430         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2431                 if ((*i)->destructive())  //ignore tape tracks when getting max extents
2432                         continue;
2433                 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2434                 if ((me = pl->get_maximum_extent()) > max) {
2435                         max = me;
2436                 }
2437         }
2438
2439         return max;
2440 }
2441
2442 boost::shared_ptr<Diskstream>
2443 Session::diskstream_by_name (string name)
2444 {
2445         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2446
2447         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2448                 if ((*i)->name() == name) {
2449                         return *i;
2450                 }
2451         }
2452
2453         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2454 }
2455
2456 boost::shared_ptr<Diskstream>
2457 Session::diskstream_by_id (const PBD::ID& id)
2458 {
2459         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2460
2461         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2462                 if ((*i)->id() == id) {
2463                         return *i;
2464                 }
2465         }
2466
2467         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2468 }
2469
2470 /* Region management */
2471
2472 string
2473 Session::new_region_name (string old)
2474 {
2475         string::size_type last_period;
2476         uint32_t number;
2477         string::size_type len = old.length() + 64;
2478         char buf[len];
2479
2480         if ((last_period = old.find_last_of ('.')) == string::npos) {
2481
2482                 /* no period present - add one explicitly */
2483
2484                 old += '.';
2485                 last_period = old.length() - 1;
2486                 number = 0;
2487
2488         } else {
2489
2490                 number = atoi (old.substr (last_period+1).c_str());
2491
2492         }
2493
2494         while (number < (UINT_MAX-1)) {
2495
2496                 RegionList::const_iterator i;
2497                 string sbuf;
2498
2499                 number++;
2500
2501                 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2502                 sbuf = buf;
2503
2504                 for (i = regions.begin(); i != regions.end(); ++i) {
2505                         if (i->second->name() == sbuf) {
2506                                 break;
2507                         }
2508                 }
2509
2510                 if (i == regions.end()) {
2511                         break;
2512                 }
2513         }
2514
2515         if (number != (UINT_MAX-1)) {
2516                 return buf;
2517         }
2518
2519         error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2520         return old;
2521 }
2522
2523 int
2524 Session::region_name (string& result, string base, bool newlevel)
2525 {
2526         char buf[16];
2527         string subbase;
2528
2529         assert(base.find("/") == string::npos);
2530
2531         if (base == "") {
2532
2533                 Glib::Mutex::Lock lm (region_lock);
2534
2535                 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2536                 result = "region.";
2537                 result += buf;
2538
2539         } else {
2540
2541                 if (newlevel) {
2542                         subbase = base;
2543                 } else {
2544                         string::size_type pos;
2545
2546                         pos = base.find_last_of ('.');
2547
2548                         /* pos may be npos, but then we just use entire base */
2549
2550                         subbase = base.substr (0, pos);
2551
2552                 }
2553
2554                 {
2555                         Glib::Mutex::Lock lm (region_lock);
2556
2557                         map<string,uint32_t>::iterator x;
2558
2559                         result = subbase;
2560
2561                         if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2562                                 result += ".1";
2563                                 region_name_map[subbase] = 1;
2564                         } else {
2565                                 x->second++;
2566                                 snprintf (buf, sizeof (buf), ".%d", x->second);
2567
2568                                 result += buf;
2569                         }
2570                 }
2571         }
2572
2573         return 0;
2574 }
2575
2576 void
2577 Session::add_region (boost::shared_ptr<Region> region)
2578 {
2579         vector<boost::shared_ptr<Region> > v;
2580         v.push_back (region);
2581         add_regions (v);
2582 }
2583
2584 void
2585 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2586 {
2587         bool added = false;
2588
2589         {
2590                 Glib::Mutex::Lock lm (region_lock);
2591
2592                 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2593
2594                         boost::shared_ptr<Region> region = *ii;
2595
2596                         if (region == 0) {
2597
2598                                 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2599
2600                         } else {
2601
2602                                 RegionList::iterator x;
2603
2604                                 for (x = regions.begin(); x != regions.end(); ++x) {
2605
2606                                         if (region->region_list_equivalent (x->second)) {
2607                                                 break;
2608                                         }
2609                                 }
2610
2611                                 if (x == regions.end()) {
2612
2613                                         pair<RegionList::key_type,RegionList::mapped_type> entry;
2614
2615                                         entry.first = region->id();
2616                                         entry.second = region;
2617
2618                                         pair<RegionList::iterator,bool> x = regions.insert (entry);
2619
2620                                         if (!x.second) {
2621                                                 return;
2622                                         }
2623
2624                                         added = true;
2625                                 }
2626                         }
2627                 }
2628         }
2629
2630         /* mark dirty because something has changed even if we didn't
2631            add the region to the region list.
2632         */
2633
2634         set_dirty ();
2635
2636         if (added) {
2637
2638                 vector<boost::weak_ptr<Region> > v;
2639                 boost::shared_ptr<Region> first_r;
2640
2641                 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2642
2643                         boost::shared_ptr<Region> region = *ii;
2644
2645                         if (region == 0) {
2646
2647                                 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2648
2649                         } else {
2650                                 v.push_back (region);
2651
2652                                 if (!first_r) {
2653                                         first_r = region;
2654                                 }
2655                         }
2656
2657                         region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2658                         region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2659
2660                         update_region_name_map (region);
2661                 }
2662
2663                 if (!v.empty()) {
2664                         RegionsAdded (v); /* EMIT SIGNAL */
2665                 }
2666         }
2667 }
2668
2669 void
2670 Session::update_region_name_map (boost::shared_ptr<Region> region)
2671 {
2672         string::size_type last_period = region->name().find_last_of ('.');
2673         
2674         if (last_period != string::npos && last_period < region->name().length() - 1) {
2675                 
2676                 string base = region->name().substr (0, last_period);
2677                 string number = region->name().substr (last_period+1);
2678                 map<string,uint32_t>::iterator x;
2679                 
2680                 /* note that if there is no number, we get zero from atoi,
2681                    which is just fine
2682                 */
2683                 
2684                 region_name_map[base] = atoi (number);
2685         }
2686 }
2687
2688 void
2689 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2690 {
2691         boost::shared_ptr<Region> region (weak_region.lock ());
2692
2693         if (!region) {
2694                 return;
2695         }
2696
2697         if (what_changed & Region::HiddenChanged) {
2698                 /* relay hidden changes */
2699                 RegionHiddenChange (region);
2700         }
2701
2702         if (what_changed & NameChanged) {
2703                 update_region_name_map (region);
2704         }
2705 }
2706
2707 void
2708 Session::remove_region (boost::weak_ptr<Region> weak_region)
2709 {
2710         RegionList::iterator i;
2711         boost::shared_ptr<Region> region (weak_region.lock ());
2712
2713         if (!region) {
2714                 return;
2715         }
2716
2717         bool removed = false;
2718
2719         {
2720                 Glib::Mutex::Lock lm (region_lock);
2721
2722                 if ((i = regions.find (region->id())) != regions.end()) {
2723                         regions.erase (i);
2724                         removed = true;
2725                 }
2726         }
2727
2728         /* mark dirty because something has changed even if we didn't
2729            remove the region from the region list.
2730         */
2731
2732         set_dirty();
2733
2734         if (removed) {
2735                  RegionRemoved(region); /* EMIT SIGNAL */
2736         }
2737 }
2738
2739 boost::shared_ptr<Region>
2740 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2741 {
2742         RegionList::iterator i;
2743         boost::shared_ptr<Region> region;
2744
2745         Glib::Mutex::Lock lm (region_lock);
2746
2747         for (i = regions.begin(); i != regions.end(); ++i) {
2748
2749                 region = i->second;
2750
2751                 if (region->whole_file()) {
2752
2753                         if (child->source_equivalent (region)) {
2754                                 return region;
2755                         }
2756                 }
2757         }
2758
2759         return boost::shared_ptr<Region> ();
2760 }
2761
2762 void
2763 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2764 {
2765         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2766                 (*i)->get_region_list_equivalent_regions (region, result);
2767 }
2768
2769 int
2770 Session::destroy_region (boost::shared_ptr<Region> region)
2771 {
2772         vector<boost::shared_ptr<Source> > srcs;
2773
2774         {
2775                 if (region->playlist()) {
2776                         region->playlist()->destroy_region (region);
2777                 }
2778
2779                 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2780                         srcs.push_back (region->source (n));
2781                 }
2782         }
2783
2784         region->drop_references ();
2785
2786         for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2787
2788                         (*i)->mark_for_remove ();
2789                         (*i)->drop_references ();
2790
2791                         cerr << "source was not used by any playlist\n";
2792         }
2793
2794         return 0;
2795 }
2796
2797 int
2798 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2799 {
2800         for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2801                 destroy_region (*i);
2802         }
2803         return 0;
2804 }
2805
2806 int
2807 Session::remove_last_capture ()
2808 {
2809         list<boost::shared_ptr<Region> > r;
2810
2811         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2812
2813         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2814                 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2815
2816                 if (!l.empty()) {
2817                         r.insert (r.end(), l.begin(), l.end());
2818                         l.clear ();
2819                 }
2820         }
2821
2822         destroy_regions (r);
2823
2824         save_state (_current_snapshot_name);
2825
2826         return 0;
2827 }
2828
2829 int
2830 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2831 {
2832         remove_region (r);
2833         return 0;
2834 }
2835
2836 /* Source Management */
2837 void
2838 Session::add_source (boost::shared_ptr<Source> source)
2839 {
2840         pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2841         pair<SourceMap::iterator,bool> result;
2842
2843         entry.first = source->id();
2844         entry.second = source;
2845
2846         {
2847                 Glib::Mutex::Lock lm (source_lock);
2848                 result = sources.insert (entry);
2849         }
2850
2851         if (result.second) {
2852                 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2853                 set_dirty();
2854         }
2855
2856         boost::shared_ptr<AudioFileSource> afs;
2857
2858         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2859                 if (Config->get_auto_analyse_audio()) {
2860                         Analyser::queue_source_for_analysis (source, false);
2861                 }
2862         }
2863 }
2864
2865 void
2866 Session::remove_source (boost::weak_ptr<Source> src)
2867 {
2868         SourceMap::iterator i;
2869         boost::shared_ptr<Source> source = src.lock();
2870
2871         if (!source) {
2872                 return;
2873         }
2874
2875         {
2876                 Glib::Mutex::Lock lm (source_lock);
2877
2878                 if ((i = sources.find (source->id())) != sources.end()) {
2879                         sources.erase (i);
2880                 }
2881         }
2882
2883         if (!_state_of_the_state & InCleanup) {
2884
2885                 /* save state so we don't end up with a session file
2886                    referring to non-existent sources.
2887                 */
2888
2889                 save_state (_current_snapshot_name);
2890         }
2891 }
2892
2893 boost::shared_ptr<Source>
2894 Session::source_by_id (const PBD::ID& id)
2895 {
2896         Glib::Mutex::Lock lm (source_lock);
2897         SourceMap::iterator i;
2898         boost::shared_ptr<Source> source;
2899
2900         if ((i = sources.find (id)) != sources.end()) {
2901                 source = i->second;
2902         }
2903
2904         return source;
2905 }
2906
2907
2908 boost::shared_ptr<Source>
2909 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2910 {
2911         Glib::Mutex::Lock lm (source_lock);
2912
2913         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2914                 cerr << "comparing " << path << " with " << i->second->name() << endl;
2915                 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2916
2917                 if (afs && afs->path() == path && chn == afs->channel()) {
2918                         return afs;
2919                 }
2920
2921         }
2922         return boost::shared_ptr<Source>();
2923 }
2924
2925 Glib::ustring
2926 Session::peak_path (Glib::ustring base) const
2927 {
2928         sys::path peakfile_path(_session_dir->peak_path());
2929         peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2930         return peakfile_path.to_string();
2931 }
2932
2933 string
2934 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2935 {
2936         string look_for;
2937         string old_basename = PBD::basename_nosuffix (oldname);
2938         string new_legalized = legalize_for_path (newname);
2939
2940         /* note: we know (or assume) the old path is already valid */
2941
2942         if (destructive) {
2943
2944                 /* destructive file sources have a name of the form:
2945
2946                     /path/to/Tnnnn-NAME(%[LR])?.wav
2947
2948                     the task here is to replace NAME with the new name.
2949                 */
2950
2951                 /* find last slash */
2952
2953                 string dir;
2954                 string prefix;
2955                 string::size_type slash;
2956                 string::size_type dash;
2957
2958                 if ((slash = path.find_last_of ('/')) == string::npos) {
2959                         return "";
2960                 }
2961
2962                 dir = path.substr (0, slash+1);
2963
2964                 /* '-' is not a legal character for the NAME part of the path */
2965
2966                 if ((dash = path.find_last_of ('-')) == string::npos) {
2967                         return "";
2968                 }
2969
2970                 prefix = path.substr (slash+1, dash-(slash+1));
2971
2972                 path = dir;
2973                 path += prefix;
2974                 path += '-';
2975                 path += new_legalized;
2976                 path += ".wav";  /* XXX gag me with a spoon */
2977
2978         } else {
2979
2980                 /* non-destructive file sources have a name of the form:
2981
2982                     /path/to/NAME-nnnnn(%[LR])?.wav
2983
2984                     the task here is to replace NAME with the new name.
2985                 */
2986
2987                 string dir;
2988                 string suffix;
2989                 string::size_type slash;
2990                 string::size_type dash;
2991                 string::size_type postfix;
2992
2993                 /* find last slash */
2994
2995                 if ((slash = path.find_last_of ('/')) == string::npos) {
2996                         return "";
2997                 }
2998
2999                 dir = path.substr (0, slash+1);
3000
3001                 /* '-' is not a legal character for the NAME part of the path */
3002
3003                 if ((dash = path.find_last_of ('-')) == string::npos) {
3004                         return "";
3005                 }
3006
3007                 suffix = path.substr (dash+1);
3008
3009                 // Suffix is now everything after the dash. Now we need to eliminate
3010                 // the nnnnn part, which is done by either finding a '%' or a '.'
3011
3012                 postfix = suffix.find_last_of ("%");
3013                 if (postfix == string::npos) {
3014                         postfix = suffix.find_last_of ('.');
3015                 }
3016
3017                 if (postfix != string::npos) {
3018                         suffix = suffix.substr (postfix);
3019                 } else {
3020                         error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3021                         return "";
3022                 }
3023
3024                 const uint32_t limit = 10000;
3025                 char buf[PATH_MAX+1];
3026
3027                 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3028
3029                         snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3030
3031                         if (access (buf, F_OK) != 0) {
3032                                 path = buf;
3033                                 break;
3034                         }
3035                         path = "";
3036                 }
3037
3038                 if (path == "") {
3039                         error << "FATAL ERROR! Could not find a " << endl;
3040                 }
3041
3042         }
3043
3044         return path;
3045 }
3046
3047 string
3048 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3049 {
3050         string spath;
3051         uint32_t cnt;
3052         char buf[PATH_MAX+1];
3053         const uint32_t limit = 10000;
3054         string legalized;
3055
3056         buf[0] = '\0';
3057         legalized = legalize_for_path (name);
3058
3059         /* find a "version" of the file name that doesn't exist in
3060            any of the possible directories.
3061         */
3062
3063         for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3064
3065                 vector<space_and_path>::iterator i;
3066                 uint32_t existing = 0;
3067
3068                 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3069
3070                         SessionDirectory sdir((*i).path);
3071
3072                         spath = sdir.sound_path().to_string();
3073
3074                         if (destructive) {
3075                                 if (nchan < 2) {
3076                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3077                                 } else if (nchan == 2) {
3078                                         if (chan == 0) {
3079                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3080                                         } else {
3081                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3082                                         }
3083                                 } else if (nchan < 26) {
3084                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3085                                 } else {
3086                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3087                                 }
3088
3089                         } else {
3090
3091                                 spath += '/';
3092                                 spath += legalized;
3093
3094                                 if (nchan < 2) {
3095                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3096                                 } else if (nchan == 2) {
3097                                         if (chan == 0) {
3098                                                 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3099                                         } else {
3100                                                 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3101                                         }
3102                                 } else if (nchan < 26) {
3103                                         snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3104                                 } else {
3105                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3106                                 }
3107                         }
3108
3109                         if (sys::exists(buf)) {
3110                                 existing++;
3111                         }
3112
3113                 }
3114
3115                 if (existing == 0) {
3116                         break;
3117                 }
3118
3119                 if (cnt > limit) {
3120                         error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3121                         destroy ();
3122                         throw failed_constructor();
3123                 }
3124         }
3125
3126         /* we now have a unique name for the file, but figure out where to
3127            actually put it.
3128         */
3129
3130         string foo = buf;
3131
3132         SessionDirectory sdir(get_best_session_directory_for_new_source ());
3133
3134         spath = sdir.sound_path().to_string();
3135         spath += '/';
3136
3137         string::size_type pos = foo.find_last_of ('/');
3138
3139         if (pos == string::npos) {
3140                 spath += foo;
3141         } else {
3142                 spath += foo.substr (pos + 1);
3143         }
3144
3145         return spath;
3146 }
3147
3148 boost::shared_ptr<AudioFileSource>
3149 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3150 {
3151         string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3152         return boost::dynamic_pointer_cast<AudioFileSource> (
3153                 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3154 }
3155
3156 // FIXME: _terrible_ code duplication
3157 string
3158 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3159 {
3160         string look_for;
3161         string old_basename = PBD::basename_nosuffix (oldname);
3162         string new_legalized = legalize_for_path (newname);
3163
3164         /* note: we know (or assume) the old path is already valid */
3165
3166         if (destructive) {
3167
3168                 /* destructive file sources have a name of the form:
3169
3170                     /path/to/Tnnnn-NAME(%[LR])?.wav
3171
3172                     the task here is to replace NAME with the new name.
3173                 */
3174
3175                 /* find last slash */
3176
3177                 string dir;
3178                 string prefix;
3179                 string::size_type slash;
3180                 string::size_type dash;
3181
3182                 if ((slash = path.find_last_of ('/')) == string::npos) {
3183                         return "";
3184                 }
3185
3186                 dir = path.substr (0, slash+1);
3187
3188                 /* '-' is not a legal character for the NAME part of the path */
3189
3190                 if ((dash = path.find_last_of ('-')) == string::npos) {
3191                         return "";
3192                 }
3193
3194                 prefix = path.substr (slash+1, dash-(slash+1));
3195
3196                 path = dir;
3197                 path += prefix;
3198                 path += '-';
3199                 path += new_legalized;
3200                 path += ".mid";  /* XXX gag me with a spoon */
3201
3202         } else {
3203
3204                 /* non-destructive file sources have a name of the form:
3205
3206                     /path/to/NAME-nnnnn(%[LR])?.wav
3207
3208                     the task here is to replace NAME with the new name.
3209                 */
3210
3211                 string dir;
3212                 string suffix;
3213                 string::size_type slash;
3214                 string::size_type dash;
3215                 string::size_type postfix;
3216
3217                 /* find last slash */
3218
3219                 if ((slash = path.find_last_of ('/')) == string::npos) {
3220                         return "";
3221                 }
3222
3223                 dir = path.substr (0, slash+1);
3224
3225                 /* '-' is not a legal character for the NAME part of the path */
3226
3227                 if ((dash = path.find_last_of ('-')) == string::npos) {
3228                         return "";
3229                 }
3230
3231                 suffix = path.substr (dash+1);
3232
3233                 // Suffix is now everything after the dash. Now we need to eliminate
3234                 // the nnnnn part, which is done by either finding a '%' or a '.'
3235
3236                 postfix = suffix.find_last_of ("%");
3237                 if (postfix == string::npos) {
3238                         postfix = suffix.find_last_of ('.');
3239                 }
3240
3241                 if (postfix != string::npos) {
3242                         suffix = suffix.substr (postfix);
3243                 } else {
3244                         error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3245                         return "";
3246                 }
3247
3248                 const uint32_t limit = 10000;
3249                 char buf[PATH_MAX+1];
3250
3251                 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3252
3253                         snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3254
3255                         if (access (buf, F_OK) != 0) {
3256                                 path = buf;
3257                                 break;
3258                         }
3259                         path = "";
3260                 }
3261
3262                 if (path == "") {
3263                         error << "FATAL ERROR! Could not find a " << endl;
3264                 }
3265
3266         }
3267
3268         return path;
3269 }
3270
3271 string
3272 Session::midi_path_from_name (string name)
3273 {
3274         string spath;
3275         uint32_t cnt;
3276         char buf[PATH_MAX+1];
3277         const uint32_t limit = 10000;
3278         string legalized;
3279
3280         buf[0] = '\0';
3281         legalized = legalize_for_path (name);
3282
3283         /* find a "version" of the file name that doesn't exist in
3284            any of the possible directories.
3285         */
3286
3287         for (cnt = 1; cnt <= limit; ++cnt) {
3288
3289                 vector<space_and_path>::iterator i;
3290                 uint32_t existing = 0;
3291
3292                 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3293
3294                         SessionDirectory sdir((*i).path);
3295
3296                         sys::path p = sdir.midi_path();
3297
3298                         p /= legalized;
3299
3300                         spath = p.to_string();
3301
3302                         snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3303
3304                         if (sys::exists (buf)) {
3305                                 existing++;
3306                         }
3307                 }
3308
3309                 if (existing == 0) {
3310                         break;
3311                 }
3312
3313                 if (cnt > limit) {
3314                         error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3315                         throw failed_constructor();
3316                 }
3317         }
3318
3319         /* we now have a unique name for the file, but figure out where to
3320            actually put it.
3321         */
3322
3323         string foo = buf;
3324
3325         SessionDirectory sdir(get_best_session_directory_for_new_source ());
3326
3327         spath = sdir.midi_path().to_string();
3328         spath += '/';
3329
3330         string::size_type pos = foo.find_last_of ('/');
3331
3332         if (pos == string::npos) {
3333                 spath += foo;
3334         } else {
3335                 spath += foo.substr (pos + 1);
3336         }
3337
3338         return spath;
3339 }
3340
3341 boost::shared_ptr<MidiSource>
3342 Session::create_midi_source_for_session (MidiDiskstream& ds)
3343 {
3344         string mpath = midi_path_from_name (ds.name());
3345
3346         return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3347 }
3348
3349
3350 /* Playlist management */
3351
3352 boost::shared_ptr<Playlist>
3353 Session::playlist_by_name (string name)
3354 {
3355         Glib::Mutex::Lock lm (playlist_lock);
3356         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3357                 if ((*i)->name() == name) {
3358                         return* i;
3359                 }
3360         }
3361         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3362                 if ((*i)->name() == name) {
3363                         return* i;
3364                 }
3365         }
3366
3367         return boost::shared_ptr<Playlist>();
3368 }
3369
3370 void
3371 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3372 {
3373         Glib::Mutex::Lock lm (playlist_lock);
3374         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3375                 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3376                         list.push_back (*i);
3377                 }
3378         }
3379         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3380                 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3381                         list.push_back (*i);
3382                 }
3383         }
3384 }
3385
3386 void
3387 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3388 {
3389         if (playlist->hidden()) {
3390                 return;
3391         }
3392
3393         {
3394                 Glib::Mutex::Lock lm (playlist_lock);
3395                 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3396                         playlists.insert (playlists.begin(), playlist);
3397                         playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3398                         playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3399                 }
3400         }
3401
3402         if (unused) {
3403                 playlist->release();
3404         }
3405
3406         set_dirty();
3407
3408         PlaylistAdded (playlist); /* EMIT SIGNAL */
3409 }
3410
3411 void
3412 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3413 {
3414         {
3415                 Glib::Mutex::Lock lm (playlist_lock);
3416                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3417                         s.push_back (*i);
3418                 }
3419                 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3420                         s.push_back (*i);
3421                 }
3422         }
3423 }
3424
3425 void
3426 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3427 {
3428         boost::shared_ptr<Playlist> pl(wpl.lock());
3429
3430         if (!pl) {
3431                 return;
3432         }
3433
3434         PlaylistList::iterator x;
3435
3436         if (pl->hidden()) {
3437                 /* its not supposed to be visible */
3438                 return;
3439         }
3440
3441         {
3442                 Glib::Mutex::Lock lm (playlist_lock);
3443
3444                 if (!inuse) {
3445
3446                         unused_playlists.insert (pl);
3447
3448                         if ((x = playlists.find (pl)) != playlists.end()) {
3449                                 playlists.erase (x);
3450                         }
3451
3452
3453                 } else {
3454
3455                         playlists.insert (pl);
3456
3457                         if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3458                                 unused_playlists.erase (x);
3459                         }
3460                 }
3461         }
3462 }
3463
3464 void
3465 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3466 {
3467         if (_state_of_the_state & Deletion) {
3468                 return;
3469         }
3470
3471         boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3472
3473         if (!playlist) {
3474                 return;
3475         }
3476
3477         {
3478                 Glib::Mutex::Lock lm (playlist_lock);
3479
3480                 PlaylistList::iterator i;
3481
3482                 i = find (playlists.begin(), playlists.end(), playlist);
3483                 if (i != playlists.end()) {
3484                         playlists.erase (i);
3485                 }
3486
3487                 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3488                 if (i != unused_playlists.end()) {
3489                         unused_playlists.erase (i);
3490                 }
3491
3492         }
3493
3494         set_dirty();
3495
3496         PlaylistRemoved (playlist); /* EMIT SIGNAL */
3497 }
3498
3499 void
3500 Session::set_audition (boost::shared_ptr<Region> r)
3501 {
3502         pending_audition_region = r;
3503         post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3504         schedule_butler_transport_work ();
3505 }
3506
3507 void
3508 Session::audition_playlist ()
3509 {
3510         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3511         ev->region.reset ();
3512         queue_event (ev);
3513 }
3514
3515 void
3516 Session::non_realtime_set_audition ()
3517 {
3518         if (!pending_audition_region) {
3519                 auditioner->audition_current_playlist ();
3520         } else {
3521                 auditioner->audition_region (pending_audition_region);
3522                 pending_audition_region.reset ();
3523         }
3524         AuditionActive (true); /* EMIT SIGNAL */
3525 }
3526
3527 void
3528 Session::audition_region (boost::shared_ptr<Region> r)
3529 {
3530         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3531         ev->region = r;
3532         queue_event (ev);
3533 }
3534
3535 void
3536 Session::cancel_audition ()
3537 {
3538         if (auditioner->active()) {
3539                 auditioner->cancel_audition ();
3540                 AuditionActive (false); /* EMIT SIGNAL */
3541         }
3542 }
3543
3544 bool
3545 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3546 {
3547         return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3548 }
3549
3550 void
3551 Session::remove_empty_sounds ()
3552 {
3553         vector<string> audio_filenames;
3554
3555         get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3556
3557         Glib::Mutex::Lock lm (source_lock);
3558
3559         TapeFileMatcher tape_file_matcher;
3560
3561         remove_if (audio_filenames.begin(), audio_filenames.end(),
3562                         sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3563
3564         for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3565
3566                 sys::path audio_file_path (_session_dir->sound_path());
3567
3568                 audio_file_path /= *i;
3569
3570                 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3571
3572                         try
3573                         {
3574                                 sys::remove (audio_file_path);
3575                                 const string peakfile = peak_path (audio_file_path.to_string());
3576                                 sys::remove (peakfile);
3577                         }
3578                         catch (const sys::filesystem_error& err)
3579                         {
3580                                 error << err.what() << endmsg;
3581                         }
3582                 }
3583         }
3584 }
3585
3586 bool
3587 Session::is_auditioning () const
3588 {
3589         /* can be called before we have an auditioner object */
3590         if (auditioner) {
3591                 return auditioner->active();
3592         } else {
3593                 return false;
3594         }
3595 }
3596
3597 void
3598 Session::set_all_solo (bool yn)
3599 {
3600         shared_ptr<RouteList> r = routes.reader ();
3601
3602         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3603                 if (!(*i)->is_hidden()) {
3604                         (*i)->set_solo (yn, this);
3605                 }
3606         }
3607
3608         set_dirty();
3609 }
3610
3611 void
3612 Session::set_all_mute (bool yn)
3613 {
3614         shared_ptr<RouteList> r = routes.reader ();
3615
3616         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3617                 if (!(*i)->is_hidden()) {
3618                         (*i)->set_mute (yn, this);
3619                 }
3620         }
3621
3622         set_dirty();
3623 }
3624
3625 uint32_t
3626 Session::n_diskstreams () const
3627 {
3628         uint32_t n = 0;
3629
3630         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3631
3632         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3633                 if (!(*i)->hidden()) {
3634                         n++;
3635                 }
3636         }
3637         return n;
3638 }
3639
3640 void
3641 Session::graph_reordered ()
3642 {
3643         /* don't do this stuff if we are setting up connections
3644            from a set_state() call or creating new tracks.
3645         */
3646
3647         if (_state_of_the_state & InitialConnecting) {
3648                 return;
3649         }
3650
3651         /* every track/bus asked for this to be handled but it was deferred because
3652            we were connecting. do it now.
3653         */
3654
3655         request_input_change_handling ();
3656
3657         resort_routes ();
3658
3659         /* force all diskstreams to update their capture offset values to
3660            reflect any changes in latencies within the graph.
3661         */
3662
3663         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3664
3665         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3666                 (*i)->set_capture_offset ();
3667         }
3668 }
3669
3670 void
3671 Session::record_disenable_all ()
3672 {
3673         record_enable_change_all (false);
3674 }
3675
3676 void
3677 Session::record_enable_all ()
3678 {
3679         record_enable_change_all (true);
3680 }
3681
3682 void
3683 Session::record_enable_change_all (bool yn)
3684 {
3685         shared_ptr<RouteList> r = routes.reader ();
3686
3687         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3688                 Track* at;
3689
3690                 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3691                         at->set_record_enable (yn, this);
3692                 }
3693         }
3694
3695         /* since we don't keep rec-enable state, don't mark session dirty */
3696 }
3697
3698 void
3699 Session::add_processor (Processor* processor)
3700 {
3701         Send* send;
3702         PortInsert* port_insert;
3703         PluginInsert* plugin_insert;
3704
3705         if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3706                 _port_inserts.insert (_port_inserts.begin(), port_insert);
3707         } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3708                 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3709         } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3710                 _sends.insert (_sends.begin(), send);
3711         } else {
3712                 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3713                 /*NOTREACHED*/
3714         }
3715
3716         processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3717
3718         set_dirty();
3719 }
3720
3721 void
3722 Session::remove_processor (Processor* processor)
3723 {
3724         Send* send;
3725         PortInsert* port_insert;
3726         PluginInsert* plugin_insert;
3727
3728         if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3729                 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3730                 if (x != _port_inserts.end()) {
3731                         insert_bitset[port_insert->bit_slot()] = false;
3732                         _port_inserts.erase (x);
3733                 }
3734         } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3735                 _plugin_inserts.remove (plugin_insert);
3736         } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3737                 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3738                 if (x != _sends.end()) {
3739                         send_bitset[send->bit_slot()] = false;
3740                         _sends.erase (x);
3741                 }
3742         } else {
3743                 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3744                 /*NOTREACHED*/
3745         }
3746
3747         set_dirty();
3748 }
3749
3750 nframes_t
3751 Session::available_capture_duration ()
3752 {
3753         float sample_bytes_on_disk = 4.0; // keep gcc happy
3754
3755         switch (Config->get_native_file_data_format()) {
3756         case FormatFloat:
3757                 sample_bytes_on_disk = 4.0;
3758                 break;
3759
3760         case FormatInt24:
3761                 sample_bytes_on_disk = 3.0;
3762                 break;
3763
3764         case FormatInt16:
3765                 sample_bytes_on_disk = 2.0;
3766                 break;
3767
3768         default:
3769                 /* impossible, but keep some gcc versions happy */
3770                 fatal << string_compose (_("programming error: %1"),
3771                                          X_("illegal native file data format"))
3772                       << endmsg;
3773                 /*NOTREACHED*/
3774         }
3775
3776         double scale = 4096.0 / sample_bytes_on_disk;
3777
3778         if (_total_free_4k_blocks * scale > (double) max_frames) {
3779                 return max_frames;
3780         }
3781
3782         return (nframes_t) floor (_total_free_4k_blocks * scale);
3783 }
3784
3785 void
3786 Session::add_bundle (shared_ptr<Bundle> bundle)
3787 {
3788         {
3789                 Glib::Mutex::Lock guard (bundle_lock);
3790                 _bundles.push_back (bundle);
3791         }
3792
3793         BundleAdded (bundle); /* EMIT SIGNAL */
3794
3795         set_dirty();
3796 }
3797
3798 void
3799 Session::remove_bundle (shared_ptr<Bundle> bundle)
3800 {
3801         bool removed = false;
3802
3803         {
3804                 Glib::Mutex::Lock guard (bundle_lock);
3805                 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3806
3807                 if (i != _bundles.end()) {
3808                         _bundles.erase (i);
3809                         removed = true;
3810                 }
3811         }
3812
3813         if (removed) {
3814                  BundleRemoved (bundle); /* EMIT SIGNAL */
3815         }
3816
3817         set_dirty();
3818 }
3819
3820 shared_ptr<Bundle>
3821 Session::bundle_by_name (string name) const
3822 {
3823         Glib::Mutex::Lock lm (bundle_lock);
3824
3825         for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3826                 if ((*i)->name() == name) {
3827                         return* i;
3828                 }
3829         }
3830
3831         return boost::shared_ptr<Bundle> ();
3832 }
3833
3834 void
3835 Session::tempo_map_changed (Change ignored)
3836 {
3837         clear_clicks ();
3838
3839         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3840                 (*i)->update_after_tempo_map_change ();
3841         }
3842
3843         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3844                 (*i)->update_after_tempo_map_change ();
3845         }
3846
3847         set_dirty ();
3848 }
3849
3850 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3851  * the given count with the current block size.
3852  */
3853 void
3854 Session::ensure_buffers (ChanCount howmany)
3855 {
3856         if (current_block_size == 0)
3857                 return; // too early? (is this ok?)
3858
3859         // We need at least 2 MIDI scratch buffers to mix/merge
3860         if (howmany.n_midi() < 2)
3861                 howmany.set_midi(2);
3862
3863         // FIXME: JACK needs to tell us maximum MIDI buffer size
3864         // Using nasty assumption (max # events == nframes) for now
3865         _scratch_buffers->ensure_buffers(howmany, current_block_size);
3866         _mix_buffers->ensure_buffers(howmany, current_block_size);
3867         _silent_buffers->ensure_buffers(howmany, current_block_size);
3868
3869         allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3870 }
3871
3872 uint32_t
3873 Session::next_insert_id ()
3874 {
3875         /* this doesn't really loop forever. just think about it */
3876
3877         while (true) {
3878                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3879                         if (!insert_bitset[n]) {
3880                                 insert_bitset[n] = true;
3881                                 return n;
3882
3883                         }
3884                 }
3885
3886                 /* none available, so resize and try again */
3887
3888                 insert_bitset.resize (insert_bitset.size() + 16, false);
3889         }
3890 }
3891
3892 uint32_t
3893 Session::next_send_id ()
3894 {
3895         /* this doesn't really loop forever. just think about it */
3896
3897         while (true) {
3898                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3899                         if (!send_bitset[n]) {
3900                                 send_bitset[n] = true;
3901                                 return n;
3902
3903                         }
3904                 }
3905
3906                 /* none available, so resize and try again */
3907
3908                 send_bitset.resize (send_bitset.size() + 16, false);
3909         }
3910 }
3911
3912 void
3913 Session::mark_send_id (uint32_t id)
3914 {
3915         if (id >= send_bitset.size()) {
3916                 send_bitset.resize (id+16, false);
3917         }
3918         if (send_bitset[id]) {
3919                 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3920         }
3921         send_bitset[id] = true;
3922 }
3923
3924 void
3925 Session::mark_insert_id (uint32_t id)
3926 {
3927         if (id >= insert_bitset.size()) {
3928                 insert_bitset.resize (id+16, false);
3929         }
3930         if (insert_bitset[id]) {
3931                 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3932         }
3933         insert_bitset[id] = true;
3934 }
3935
3936 /* Named Selection management */
3937
3938 NamedSelection *
3939 Session::named_selection_by_name (string name)
3940 {
3941         Glib::Mutex::Lock lm (named_selection_lock);
3942         for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3943                 if ((*i)->name == name) {
3944                         return* i;
3945                 }
3946         }
3947         return 0;
3948 }
3949
3950 void
3951 Session::add_named_selection (NamedSelection* named_selection)
3952 {
3953         {
3954                 Glib::Mutex::Lock lm (named_selection_lock);
3955                 named_selections.insert (named_selections.begin(), named_selection);
3956         }
3957
3958         for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3959                 add_playlist (*i);
3960         }
3961
3962         set_dirty();
3963
3964         NamedSelectionAdded (); /* EMIT SIGNAL */
3965 }
3966
3967 void
3968 Session::remove_named_selection (NamedSelection* named_selection)
3969 {
3970         bool removed = false;
3971
3972         {
3973                 Glib::Mutex::Lock lm (named_selection_lock);
3974
3975                 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3976
3977                 if (i != named_selections.end()) {
3978                         delete (*i);
3979                         named_selections.erase (i);
3980                         set_dirty();
3981                         removed = true;
3982                 }
3983         }
3984
3985         if (removed) {
3986                  NamedSelectionRemoved (); /* EMIT SIGNAL */
3987         }
3988 }
3989
3990 void
3991 Session::reset_native_file_format ()
3992 {
3993         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3994
3995         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3996                 (*i)->reset_write_sources (false);
3997         }
3998 }
3999
4000 bool
4001 Session::route_name_unique (string n) const
4002 {
4003         shared_ptr<RouteList> r = routes.reader ();
4004
4005         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4006                 if ((*i)->name() == n) {
4007                         return false;
4008                 }
4009         }
4010
4011         return true;
4012 }
4013
4014 uint32_t
4015 Session::n_playlists () const
4016 {
4017         Glib::Mutex::Lock lm (playlist_lock);
4018         return playlists.size();
4019 }
4020
4021 void
4022 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4023 {
4024         if (!force && howmany <= _npan_buffers) {
4025                 return;
4026         }
4027
4028         if (_pan_automation_buffer) {
4029
4030                 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4031                         delete [] _pan_automation_buffer[i];
4032                 }
4033
4034                 delete [] _pan_automation_buffer;
4035         }
4036
4037         _pan_automation_buffer = new pan_t*[howmany];
4038
4039         for (uint32_t i = 0; i < howmany; ++i) {
4040                 _pan_automation_buffer[i] = new pan_t[nframes];
4041         }
4042
4043         _npan_buffers = howmany;
4044 }
4045
4046 int
4047 Session::freeze (InterThreadInfo& itt)
4048 {
4049         shared_ptr<RouteList> r = routes.reader ();
4050
4051         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4052
4053                 Track *at;
4054
4055                 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4056                         /* XXX this is wrong because itt.progress will keep returning to zero at the start
4057                            of every track.
4058                         */
4059                         at->freeze (itt);
4060                 }
4061         }
4062
4063         return 0;
4064 }
4065
4066 boost::shared_ptr<Region>
4067 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,    
4068                           bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4069 {
4070         boost::shared_ptr<Region> result;
4071         boost::shared_ptr<Playlist> playlist;
4072         boost::shared_ptr<AudioFileSource> fsource;
4073         uint32_t x;
4074         char buf[PATH_MAX+1];
4075         ChanCount nchans(track.audio_diskstream()->n_channels());
4076         nframes_t position;
4077         nframes_t this_chunk;
4078         nframes_t to_do;
4079         BufferSet buffers;
4080         SessionDirectory sdir(get_best_session_directory_for_new_source ());
4081         const string sound_dir = sdir.sound_path().to_string();
4082         nframes_t len = end - start;
4083
4084         if (end <= start) {
4085                 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4086                                          end, start) << endmsg;
4087                 return result;
4088         }
4089
4090         // any bigger than this seems to cause stack overflows in called functions
4091         const nframes_t chunk_size = (128 * 1024)/4;
4092
4093         g_atomic_int_set (&processing_prohibited, 1);
4094
4095         /* call tree *MUST* hold route_lock */
4096
4097         if ((playlist = track.diskstream()->playlist()) == 0) {
4098                 goto out;
4099         }
4100
4101         /* external redirects will be a problem */
4102
4103         if (track.has_external_redirects()) {
4104                 goto out;
4105         }
4106
4107         for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4108
4109                 for (x = 0; x < 99999; ++x) {
4110                         snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4111                         if (access (buf, F_OK) != 0) {
4112                                 break;
4113                         }
4114                 }
4115
4116                 if (x == 99999) {
4117                         error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4118                         goto out;
4119                 }
4120
4121                 try {
4122                         fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4123                                 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4124                 }
4125
4126                 catch (failed_constructor& err) {
4127                         error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4128                         goto out;
4129                 }
4130
4131                 srcs.push_back (fsource);
4132         }
4133
4134         /* XXX need to flush all redirects */
4135
4136         position = start;
4137         to_do = len;
4138
4139         /* create a set of reasonably-sized buffers */
4140         buffers.ensure_buffers(nchans, chunk_size);
4141         buffers.set_count(nchans);
4142
4143         for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4144                 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4145                 if (afs)
4146                         afs->prepare_for_peakfile_writes ();
4147         }
4148
4149         while (to_do && !itt.cancel) {
4150
4151                 this_chunk = min (to_do, chunk_size);
4152
4153                 if (track.export_stuff (buffers, start, this_chunk)) {
4154                         goto out;
4155                 }
4156
4157                 uint32_t n = 0;
4158                 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4159                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4160
4161                         if (afs) {
4162                                 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4163                                         goto out;
4164                                 }
4165                         }
4166                 }
4167
4168                 start += this_chunk;
4169                 to_do -= this_chunk;
4170
4171                 itt.progress = (float) (1.0 - ((double) to_do / len));
4172
4173         }
4174
4175         if (!itt.cancel) {
4176
4177                 time_t now;
4178                 struct tm* xnow;
4179                 time (&now);
4180                 xnow = localtime (&now);
4181
4182                 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4183                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4184
4185                         if (afs) {
4186                                 afs->update_header (position, *xnow, now);
4187                                 afs->flush_header ();
4188                         }
4189                 }
4190
4191                 /* construct a region to represent the bounced material */
4192
4193                 result = RegionFactory::create (srcs, 0, srcs.front()->length(), 
4194                                                 region_name_from_path (srcs.front()->name(), true));
4195         }
4196
4197   out:
4198         if (!result) {
4199                 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4200                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4201
4202                         if (afs) {
4203                                 afs->mark_for_remove ();
4204                         }
4205                         
4206                         (*src)->drop_references ();
4207                 }
4208
4209         } else {
4210                 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4211                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4212
4213                         if (afs)
4214                                 afs->done_with_peakfile_writes ();
4215                 }
4216         }
4217
4218         g_atomic_int_set (&processing_prohibited, 0);
4219
4220         return result;
4221 }
4222
4223 BufferSet&
4224 Session::get_silent_buffers (ChanCount count)
4225 {
4226         assert(_silent_buffers->available() >= count);
4227         _silent_buffers->set_count(count);
4228
4229         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4230                 for (size_t i= 0; i < count.get(*t); ++i) {
4231                         _silent_buffers->get(*t, i).clear();
4232                 }
4233         }
4234
4235         return *_silent_buffers;
4236 }
4237
4238 BufferSet&
4239 Session::get_scratch_buffers (ChanCount count)
4240 {
4241         assert(_scratch_buffers->available() >= count);
4242         _scratch_buffers->set_count(count);
4243         return *_scratch_buffers;
4244 }
4245
4246 BufferSet&
4247 Session::get_mix_buffers (ChanCount count)
4248 {
4249         assert(_mix_buffers->available() >= count);
4250         _mix_buffers->set_count(count);
4251         return *_mix_buffers;
4252 }
4253
4254 uint32_t
4255 Session::ntracks () const
4256 {
4257         uint32_t n = 0;
4258         shared_ptr<RouteList> r = routes.reader ();
4259
4260         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4261                 if (dynamic_cast<Track*> ((*i).get())) {
4262                         ++n;
4263                 }
4264         }
4265
4266         return n;
4267 }
4268
4269 uint32_t
4270 Session::nbusses () const
4271 {
4272         uint32_t n = 0;
4273         shared_ptr<RouteList> r = routes.reader ();
4274
4275         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4276                 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4277                         ++n;
4278                 }
4279         }
4280
4281         return n;
4282 }
4283
4284 void
4285 Session::add_automation_list(AutomationList *al)
4286 {
4287         automation_lists[al->id()] = al;
4288 }
4289
4290 nframes_t
4291 Session::compute_initial_length ()
4292 {
4293         return _engine.frame_rate() * 60 * 5;
4294 }
4295
4296 void
4297 Session::sync_order_keys ()
4298 {
4299         if (!Config->get_sync_all_route_ordering()) {
4300                 /* leave order keys as they are */
4301                 return;
4302         }
4303
4304         boost::shared_ptr<RouteList> r = routes.reader ();
4305
4306         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4307                 (*i)->sync_order_keys ();
4308         }
4309
4310         Route::SyncOrderKeys (); // EMIT SIGNAL
4311 }
4312
4313 void
4314 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4315 {
4316         Glib::Mutex::Lock lm (bundle_lock);
4317         for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
4318                 sl (*i);
4319         }
4320 }
4321