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