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