imported files retain BWF timestamp info (nick murtagh) ; logarithm plugin controls...
[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 << pfe.what() << 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 << pfe.what() << 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         uint32_t number = 1;
2046
2047         if (!tree.read (template_path.c_str())) {
2048                 return ret;
2049         }
2050
2051         XMLNode* node = tree.root();
2052
2053         control_id = ntracks() + nbusses() + 1;
2054
2055         while (how_many) {
2056
2057                 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2058           
2059                 std::string node_name = IO::name_from_state (*node_copy.children().front());
2060
2061                 /* generate a new name by adding a number to the end of the template name */
2062                 
2063                 do {
2064                         snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2065                         
2066                         number++;
2067                         
2068                         if (route_by_name (name) == 0) {
2069                                 break;
2070                         }
2071                         
2072                 } while (number < UINT_MAX);
2073                 
2074                 if (number == UINT_MAX) {
2075                         fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2076                                 /*NOTREACHED*/
2077                 }
2078                 
2079                 IO::set_name_in_state (*node_copy.children().front(), name);
2080
2081                 Track::zero_diskstream_id_in_xml (node_copy);
2082                 
2083                 try {
2084                         shared_ptr<Route> route (XMLRouteFactory (node_copy));
2085             
2086                         if (route == 0) {
2087                                 error << _("Session: cannot create track/bus from template description") << endmsg;
2088                                 goto out;
2089                         }
2090
2091                         if (boost::dynamic_pointer_cast<Track>(route)) {
2092                                 /* force input/output change signals so that the new diskstream
2093                                    picks up the configuration of the route. During session
2094                                    loading this normally happens in a different way.
2095                                 */
2096                                 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2097                                 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2098                         }
2099
2100                         route->set_remote_control_id (control_id);
2101                         ++control_id;
2102             
2103                         ret.push_back (route);
2104                 }
2105           
2106                 catch (failed_constructor &err) {
2107                         error << _("Session: could not create new route from template") << endmsg;
2108                         goto out;
2109                 }
2110           
2111                 catch (AudioEngine::PortRegistrationFailure& pfe) {
2112                         error << pfe.what() << endmsg;
2113                         goto out;
2114                 }
2115           
2116                 --how_many;
2117         }
2118
2119   out:
2120         if (!ret.empty()) {
2121                 add_routes (ret, true);
2122         }
2123
2124         return ret;
2125 }
2126
2127 boost::shared_ptr<Route>
2128 Session::new_video_track (string name)
2129 {
2130         uint32_t control_id = ntracks() + nbusses() + 1;
2131         shared_ptr<Route> new_route (
2132                 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2133         new_route->set_remote_control_id (control_id);
2134
2135         RouteList rl;
2136         rl.push_back (new_route);
2137         {
2138                 RCUWriter<RouteList> writer (routes);
2139                 shared_ptr<RouteList> r = writer.get_copy ();
2140                 r->insert (r->end(), rl.begin(), rl.end());
2141                 resort_routes_using (r);
2142         }
2143         return new_route;
2144 }
2145
2146 void
2147 Session::add_routes (RouteList& new_routes, bool save)
2148 {
2149         { 
2150                 RCUWriter<RouteList> writer (routes);
2151                 shared_ptr<RouteList> r = writer.get_copy ();
2152                 r->insert (r->end(), new_routes.begin(), new_routes.end());
2153                 resort_routes_using (r);
2154         }
2155
2156         for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2157                 
2158                 boost::weak_ptr<Route> wpr (*x);
2159
2160                 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2161                 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2162                 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2163                 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2164                 
2165                 if ((*x)->master()) {
2166                         _master_out = (*x);
2167                 }
2168                 
2169                 if ((*x)->control()) {
2170                         _control_out = (*x);
2171                 } 
2172         }
2173
2174         if (_control_out && IO::connecting_legal) {
2175
2176                 vector<string> cports;
2177                 uint32_t ni = _control_out->n_inputs();
2178                 uint32_t n;
2179
2180                 for (n = 0; n < ni; ++n) {
2181                         cports.push_back (_control_out->input(n)->name());
2182                 }
2183
2184                 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2185                         (*x)->set_control_outs (cports);
2186                 }
2187         } 
2188
2189         set_dirty();
2190
2191         if (save) {
2192                 save_state (_current_snapshot_name);
2193         }
2194
2195         RouteAdded (new_routes); /* EMIT SIGNAL */
2196 }
2197
2198 void
2199 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2200 {
2201         /* need to do this in case we're rolling at the time, to prevent false underruns */
2202         dstream->do_refill_with_alloc ();
2203         
2204         dstream->set_block_size (current_block_size);
2205
2206         {
2207                 RCUWriter<DiskstreamList> writer (diskstreams);
2208                 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2209                 ds->push_back (dstream);
2210                 /* writer goes out of scope, copies ds back to main */
2211         } 
2212
2213         dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), 
2214                                                       boost::weak_ptr<Diskstream> (dstream)));
2215         /* this will connect to future changes, and check the current length */
2216         diskstream_playlist_changed (dstream);
2217
2218         dstream->prepare ();
2219 }
2220
2221 void
2222 Session::remove_route (shared_ptr<Route> route)
2223 {
2224         {       
2225                 RCUWriter<RouteList> writer (routes);
2226                 shared_ptr<RouteList> rs = writer.get_copy ();
2227                 
2228                 rs->remove (route);
2229
2230                 /* deleting the master out seems like a dumb
2231                    idea, but its more of a UI policy issue
2232                    than our concern.
2233                 */
2234
2235                 if (route == _master_out) {
2236                         _master_out = shared_ptr<Route> ();
2237                 }
2238
2239                 if (route == _control_out) {
2240                         _control_out = shared_ptr<Route> ();
2241
2242                         /* cancel control outs for all routes */
2243
2244                         vector<string> empty;
2245
2246                         for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2247                                 (*r)->set_control_outs (empty);
2248                         }
2249                 }
2250
2251                 update_route_solo_state ();
2252                 
2253                 /* writer goes out of scope, forces route list update */
2254         }
2255
2256         // FIXME: audio specific
2257         AudioTrack* at;
2258         boost::shared_ptr<AudioDiskstream> ds;
2259         
2260         if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2261                 ds = at->audio_diskstream();
2262         }
2263         
2264         if (ds) {
2265
2266                 {
2267                         RCUWriter<DiskstreamList> dsl (diskstreams);
2268                         boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2269                         d->remove (ds);
2270                 }
2271
2272                 diskstreams.flush ();
2273         }
2274
2275         find_current_end ();
2276         
2277         // We need to disconnect the routes inputs and outputs 
2278
2279         route->disconnect_inputs (0);
2280         route->disconnect_outputs (0);
2281         
2282         update_latency_compensation (false, false);
2283         set_dirty();
2284
2285         /* get rid of it from the dead wood collection in the route list manager */
2286
2287         /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2288
2289         routes.flush ();
2290
2291         /* try to cause everyone to drop their references */
2292
2293         route->drop_references ();
2294
2295         sync_order_keys (N_("session"));
2296
2297         /* save the new state of the world */
2298
2299         if (save_state (_current_snapshot_name)) {
2300                 save_history (_current_snapshot_name);
2301         }
2302 }       
2303
2304 void
2305 Session::route_mute_changed (void* src)
2306 {
2307         set_dirty ();
2308 }
2309
2310 void
2311 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2312 {      
2313         if (solo_update_disabled) {
2314                 // We know already
2315                 return;
2316         }
2317         
2318         bool is_track;
2319         boost::shared_ptr<Route> route = wpr.lock ();
2320
2321         if (!route) {
2322                 /* should not happen */
2323                 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2324                 return;
2325         }
2326
2327         is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2328         
2329         shared_ptr<RouteList> r = routes.reader ();
2330
2331         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2332                 
2333                 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2334                 
2335                 if (is_track) {
2336                         
2337                         /* don't mess with busses */
2338                         
2339                         if (boost::dynamic_pointer_cast<AudioTrack>(*i) == 0) {
2340                                 continue;
2341                         }
2342                         
2343                 } else {
2344                         
2345                         /* don't mess with tracks */
2346                         
2347                         if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
2348                                 continue;
2349                         }
2350                 }
2351                 
2352                 if ((*i) != route &&
2353                     ((*i)->mix_group () == 0 ||
2354                      (*i)->mix_group () != route->mix_group () ||
2355                      !route->mix_group ()->is_active())) {
2356                         
2357                         if ((*i)->soloed()) {
2358                                 
2359                                 /* if its already soloed, and solo latching is enabled,
2360                                    then leave it as it is.
2361                                 */
2362                                 
2363                                 if (Config->get_solo_latched()) {
2364                                         continue;
2365                                 } 
2366                         }
2367                         
2368                         /* do it */
2369
2370                         solo_update_disabled = true;
2371                         (*i)->set_solo (false, src);
2372                         solo_update_disabled = false;
2373                 }
2374         }
2375         
2376         bool something_soloed = false;
2377         bool same_thing_soloed = false;
2378         bool signal = false;
2379
2380         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381                 if ((*i)->soloed()) {
2382                         something_soloed = true;
2383                         if (dynamic_cast<AudioTrack*>((*i).get())) {
2384                                 if (is_track) {
2385                                         same_thing_soloed = true;
2386                                         break;
2387                                 }
2388                         } else {
2389                                 if (!is_track) {
2390                                         same_thing_soloed = true;
2391                                         break;
2392                                 }
2393                         }
2394                         break;
2395                 }
2396         }
2397         
2398         if (something_soloed != currently_soloing) {
2399                 signal = true;
2400                 currently_soloing = something_soloed;
2401         }
2402         
2403         modify_solo_mute (is_track, same_thing_soloed);
2404
2405         if (signal) {
2406                 SoloActive (currently_soloing); /* EMIT SIGNAL */
2407         }
2408
2409         SoloChanged (); /* EMIT SIGNAL */
2410
2411         set_dirty();
2412 }
2413
2414 void
2415 Session::update_route_solo_state ()
2416 {
2417         bool mute = false;
2418         bool is_track = false;
2419         bool signal = false;
2420
2421         /* this is where we actually implement solo by changing
2422            the solo mute setting of each track.
2423         */
2424         
2425         shared_ptr<RouteList> r = routes.reader ();
2426
2427         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2428                 if ((*i)->soloed()) {
2429                         mute = true;
2430                         if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2431                                 is_track = true;
2432                         }
2433                         break;
2434                 }
2435         }
2436
2437         if (mute != currently_soloing) {
2438                 signal = true;
2439                 currently_soloing = mute;
2440         }
2441
2442         if (!is_track && !mute) {
2443
2444                 /* nothing is soloed */
2445
2446                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2447                         (*i)->set_solo_mute (false);
2448                 }
2449                 
2450                 if (signal) {
2451                         SoloActive (false);
2452                 }
2453
2454                 return;
2455         }
2456
2457         modify_solo_mute (is_track, mute);
2458
2459         if (signal) {
2460                 SoloActive (currently_soloing);
2461         }
2462 }
2463
2464 void
2465 Session::modify_solo_mute (bool is_track, bool mute)
2466 {
2467         shared_ptr<RouteList> r = routes.reader ();
2468
2469         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2470                 
2471                 if (is_track) {
2472                         
2473                         /* only alter track solo mute */
2474                         
2475                         if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2476                                 if ((*i)->soloed()) {
2477                                         (*i)->set_solo_mute (!mute);
2478                                 } else {
2479                                         (*i)->set_solo_mute (mute);
2480                                 }
2481                         }
2482
2483                 } else {
2484
2485                         /* only alter bus solo mute */
2486                         
2487                         if (!boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2488
2489                                 if ((*i)->soloed()) {
2490
2491                                         (*i)->set_solo_mute (false);
2492
2493                                 } else {
2494
2495                                         /* don't mute master or control outs
2496                                            in response to another bus solo
2497                                         */
2498                                         
2499                                         if ((*i) != _master_out &&
2500                                             (*i) != _control_out) {
2501                                                 (*i)->set_solo_mute (mute);
2502                                         }
2503                                 }
2504                         }
2505
2506                 }
2507         }
2508 }       
2509
2510
2511 void
2512 Session::catch_up_on_solo ()
2513 {
2514         /* this is called after set_state() to catch the full solo
2515            state, which can't be correctly determined on a per-route
2516            basis, but needs the global overview that only the session
2517            has.
2518         */
2519         update_route_solo_state();
2520 }       
2521
2522 void
2523 Session::catch_up_on_solo_mute_override ()
2524 {
2525         if (Config->get_solo_model() != InverseMute) {
2526                 return;
2527         }
2528
2529         /* this is called whenever the param solo-mute-override is
2530            changed.
2531         */
2532         shared_ptr<RouteList> r = routes.reader ();
2533
2534         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2535                 (*i)->catch_up_on_solo_mute_override ();
2536         }
2537 }       
2538
2539 shared_ptr<Route>
2540 Session::route_by_name (string name)
2541 {
2542         shared_ptr<RouteList> r = routes.reader ();
2543
2544         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2545                 if ((*i)->name() == name) {
2546                         return *i;
2547                 }
2548         }
2549
2550         return shared_ptr<Route> ((Route*) 0);
2551 }
2552
2553 shared_ptr<Route>
2554 Session::route_by_id (PBD::ID id)
2555 {
2556         shared_ptr<RouteList> r = routes.reader ();
2557
2558         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2559                 if ((*i)->id() == id) {
2560                         return *i;
2561                 }
2562         }
2563
2564         return shared_ptr<Route> ((Route*) 0);
2565 }
2566
2567 shared_ptr<Route>
2568 Session::route_by_remote_id (uint32_t id)
2569 {
2570         shared_ptr<RouteList> r = routes.reader ();
2571
2572         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2573                 if ((*i)->remote_control_id() == id) {
2574                         return *i;
2575                 }
2576         }
2577
2578         return shared_ptr<Route> ((Route*) 0);
2579 }
2580
2581 void
2582 Session::find_current_end ()
2583 {
2584         if (_state_of_the_state & Loading) {
2585                 return;
2586         }
2587
2588         nframes_t max = get_maximum_extent ();
2589
2590         if (max > end_location->end()) {
2591                 end_location->set_end (max);
2592                 set_dirty();
2593                 DurationChanged(); /* EMIT SIGNAL */
2594         }
2595 }
2596
2597 nframes_t
2598 Session::get_maximum_extent () const
2599 {
2600         nframes_t max = 0;
2601         nframes_t me; 
2602
2603         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2604
2605         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2606                 if ((*i)->destructive())  //ignore tape tracks when getting max extents
2607                         continue;
2608                 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2609                 if ((me = pl->get_maximum_extent()) > max) {
2610                         max = me;
2611                 }
2612         }
2613
2614         return max;
2615 }
2616
2617 boost::shared_ptr<Diskstream>
2618 Session::diskstream_by_name (string name)
2619 {
2620         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2621
2622         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2623                 if ((*i)->name() == name) {
2624                         return *i;
2625                 }
2626         }
2627
2628         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2629 }
2630
2631 boost::shared_ptr<Diskstream>
2632 Session::diskstream_by_id (const PBD::ID& id)
2633 {
2634         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2635
2636         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2637                 if ((*i)->id() == id) {
2638                         return *i;
2639                 }
2640         }
2641
2642         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2643 }
2644
2645 /* AudioRegion management */
2646
2647 string
2648 Session::new_region_name (string old)
2649 {
2650         string::size_type last_period;
2651         uint32_t number;
2652         string::size_type len = old.length() + 64;
2653         char buf[len];
2654
2655         if ((last_period = old.find_last_of ('.')) == string::npos) {
2656                 
2657                 /* no period present - add one explicitly */
2658
2659                 old += '.';
2660                 last_period = old.length() - 1;
2661                 number = 0;
2662
2663         } else {
2664
2665                 number = atoi (old.substr (last_period+1).c_str());
2666
2667         }
2668
2669         while (number < (UINT_MAX-1)) {
2670
2671                 AudioRegionList::const_iterator i;
2672                 string sbuf;
2673
2674                 number++;
2675
2676                 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2677                 sbuf = buf;
2678
2679                 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2680                         if (i->second->name() == sbuf) {
2681                                 break;
2682                         }
2683                 }
2684                 
2685                 if (i == audio_regions.end()) {
2686                         break;
2687                 }
2688         }
2689
2690         if (number != (UINT_MAX-1)) {
2691                 return buf;
2692         } 
2693
2694         error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2695         return old;
2696 }
2697
2698 int
2699 Session::region_name (string& result, string base, bool newlevel)
2700 {
2701         char buf[16];
2702         string subbase;
2703
2704         if (base == "") {
2705                 
2706                 Glib::Mutex::Lock lm (region_lock);
2707
2708                 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2709                 result = "region.";
2710                 result += buf;
2711
2712         } else {
2713
2714                 if (newlevel) {
2715                         subbase = base;
2716                 } else {
2717                         string::size_type pos;
2718
2719                         pos = base.find_last_of ('.');
2720
2721                         /* pos may be npos, but then we just use entire base */
2722
2723                         subbase = base.substr (0, pos);
2724
2725                 }
2726                 
2727                 {
2728                         Glib::Mutex::Lock lm (region_lock);
2729
2730                         map<string,uint32_t>::iterator x;
2731
2732                         result = subbase;
2733
2734                         if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2735                                 result += ".1";
2736                                 region_name_map[subbase] = 1;
2737                         } else {
2738                                 x->second++;
2739                                 snprintf (buf, sizeof (buf), ".%d", x->second);
2740                                 result += buf;
2741                         }
2742                 }
2743         }
2744
2745         return 0;
2746 }       
2747
2748 void
2749 Session::add_region (boost::shared_ptr<Region> region)
2750 {
2751         vector<boost::shared_ptr<Region> > v;
2752         v.push_back (region);
2753         add_regions (v);
2754 }
2755                 
2756 void
2757 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2758 {
2759         boost::shared_ptr<AudioRegion> ar;
2760         boost::shared_ptr<AudioRegion> oar;
2761         bool added = false;
2762
2763         { 
2764                 Glib::Mutex::Lock lm (region_lock);
2765
2766                 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2767                 
2768                         boost::shared_ptr<Region> region = *ii;
2769                         
2770                         if (region == 0) {
2771
2772                                 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2773
2774                         } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2775                                 
2776                                 AudioRegionList::iterator x;
2777                                 
2778                                 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2779                                         
2780                                         oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2781                                         
2782                                         if (ar->region_list_equivalent (oar)) {
2783                                                 break;
2784                                         }
2785                                 }
2786                                 
2787                                 if (x == audio_regions.end()) {
2788                                         
2789                                         pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2790                                         
2791                                         entry.first = region->id();
2792                                         entry.second = ar;
2793                                         
2794                                         pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2795                                         
2796                                         if (!x.second) {
2797                                                 return;
2798                                         }
2799                                         
2800                                         added = true;
2801                                 } 
2802
2803                         } else {
2804                                 
2805                                 fatal << _("programming error: ")
2806                                       << X_("unknown region type passed to Session::add_region()")
2807                                       << endmsg;
2808                                 /*NOTREACHED*/
2809                                 
2810                         }
2811                 }
2812         }
2813
2814         /* mark dirty because something has changed even if we didn't
2815            add the region to the region list.
2816         */
2817         
2818         set_dirty ();
2819         
2820         if (added) {
2821
2822                 vector<boost::weak_ptr<AudioRegion> > v;
2823                 boost::shared_ptr<AudioRegion> first_ar;
2824
2825                 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2826
2827                         boost::shared_ptr<Region> region = *ii;
2828                         boost::shared_ptr<AudioRegion> ar;
2829
2830                         if (region == 0) {
2831
2832                                 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2833
2834                         } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2835                                 v.push_back (ar);
2836
2837                                 if (!first_ar) {
2838                                         first_ar = ar;
2839                                 }
2840                         }
2841
2842                         region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2843                         region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2844
2845                         update_region_name_map (region);
2846                 }
2847
2848                 if (!v.empty()) {
2849                         AudioRegionsAdded (v); /* EMIT SIGNAL */
2850                 }
2851         }
2852 }
2853
2854 void
2855 Session::update_region_name_map (boost::shared_ptr<Region> region)
2856 {
2857         string::size_type last_period = region->name().find_last_of ('.');
2858         
2859         if (last_period != string::npos && last_period < region->name().length() - 1) {
2860                 
2861                 string base = region->name().substr (0, last_period);
2862                 string number = region->name().substr (last_period+1);
2863                 map<string,uint32_t>::iterator x;
2864                 
2865                 /* note that if there is no number, we get zero from atoi,
2866                    which is just fine
2867                 */
2868                 
2869                 region_name_map[base] = atoi (number);
2870         }
2871 }
2872
2873 void
2874 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2875 {
2876         boost::shared_ptr<Region> region (weak_region.lock ());
2877
2878         if (!region) {
2879                 return;
2880         }
2881
2882         if (what_changed & Region::HiddenChanged) {
2883                 /* relay hidden changes */
2884                 RegionHiddenChange (region);
2885         }
2886
2887         if (what_changed & NameChanged) {
2888                 update_region_name_map (region);
2889         }
2890 }
2891
2892 void
2893 Session::remove_region (boost::weak_ptr<Region> weak_region)
2894 {
2895         AudioRegionList::iterator i;
2896         boost::shared_ptr<Region> region (weak_region.lock ());
2897
2898         if (!region) {
2899                 return;
2900         }
2901
2902         boost::shared_ptr<AudioRegion> ar;
2903         bool removed = false;
2904
2905         { 
2906                 Glib::Mutex::Lock lm (region_lock);
2907
2908                 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2909                         if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2910                                 audio_regions.erase (i);
2911                                 removed = true;
2912                         }
2913
2914                 } else {
2915
2916                         fatal << _("programming error: ") 
2917                               << X_("unknown region type passed to Session::remove_region()")
2918                               << endmsg;
2919                         /*NOTREACHED*/
2920                 }
2921         }
2922
2923         /* mark dirty because something has changed even if we didn't
2924            remove the region from the region list.
2925         */
2926
2927         set_dirty();
2928
2929         if (removed) {
2930                 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2931         }
2932 }
2933
2934 boost::shared_ptr<AudioRegion>
2935 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2936 {
2937         AudioRegionList::iterator i;
2938         boost::shared_ptr<AudioRegion> region;
2939         Glib::Mutex::Lock lm (region_lock);
2940
2941         for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2942
2943                 region = i->second;
2944
2945                 if (region->whole_file()) {
2946
2947                         if (child->source_equivalent (region)) {
2948                                 return region;
2949                         }
2950                 }
2951         } 
2952
2953         return boost::shared_ptr<AudioRegion> ();
2954 }       
2955
2956 void
2957 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2958 {
2959         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2960                 (*i)->get_region_list_equivalent_regions (region, result);
2961 }
2962
2963 int
2964 Session::destroy_region (boost::shared_ptr<Region> region)
2965 {
2966         vector<boost::shared_ptr<Source> > srcs;
2967                 
2968         {
2969                 boost::shared_ptr<AudioRegion> aregion;
2970                 
2971                 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2972                         return 0;
2973                 }
2974                 
2975                 if (aregion->playlist()) {
2976                         aregion->playlist()->destroy_region (region);
2977                 }
2978                 
2979                 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2980                         srcs.push_back (aregion->source (n));
2981                 }
2982         }
2983
2984         region->drop_references ();
2985
2986         for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2987
2988                 if (!(*i)->used()) {
2989                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2990                         
2991                         if (afs) {
2992                                 (afs)->mark_for_remove ();
2993                         }
2994                         
2995                         (*i)->drop_references ();
2996                         
2997                         cerr << "source was not used by any playlist\n";
2998                 }
2999         }
3000
3001         return 0;
3002 }
3003
3004 int
3005 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3006 {
3007         for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3008                 destroy_region (*i);
3009         }
3010         return 0;
3011 }
3012
3013 int
3014 Session::remove_last_capture ()
3015 {
3016         list<boost::shared_ptr<Region> > r;
3017         
3018         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3019         
3020         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3021                 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3022                 
3023                 if (!l.empty()) {
3024                         r.insert (r.end(), l.begin(), l.end());
3025                         l.clear ();
3026                 }
3027         }
3028
3029         destroy_regions (r);
3030
3031         save_state (_current_snapshot_name);
3032
3033         return 0;
3034 }
3035
3036 int
3037 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3038 {
3039         remove_region (r);
3040         return 0;
3041 }
3042
3043 /* Source Management */
3044
3045 void
3046 Session::add_source (boost::shared_ptr<Source> source)
3047 {
3048         boost::shared_ptr<AudioFileSource> afs;
3049
3050         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3051
3052                 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3053                 pair<AudioSourceList::iterator,bool> result;
3054
3055                 entry.first = source->id();
3056                 entry.second = afs;
3057                 
3058                 {
3059                         Glib::Mutex::Lock lm (audio_source_lock);
3060                         result = audio_sources.insert (entry);
3061                 }
3062
3063                 if (result.second) {
3064                         source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3065                         set_dirty();
3066                 }
3067
3068                 if (Config->get_auto_analyse_audio()) {
3069                         Analyser::queue_source_for_analysis (source, false);
3070                 }
3071         } 
3072 }
3073
3074 void
3075 Session::remove_source (boost::weak_ptr<Source> src)
3076 {
3077         AudioSourceList::iterator i;
3078         boost::shared_ptr<Source> source = src.lock();
3079
3080         if (!source) {
3081                 return;
3082         } 
3083
3084         { 
3085                 Glib::Mutex::Lock lm (audio_source_lock);
3086                 
3087                 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3088                         audio_sources.erase (i);
3089                 } 
3090         }
3091         
3092         if (!_state_of_the_state & InCleanup) {
3093                 
3094                 /* save state so we don't end up with a session file
3095                    referring to non-existent sources.
3096                 */
3097                 
3098                 save_state (_current_snapshot_name);
3099         }
3100 }
3101
3102 boost::shared_ptr<Source>
3103 Session::source_by_id (const PBD::ID& id)
3104 {
3105         Glib::Mutex::Lock lm (audio_source_lock);
3106         AudioSourceList::iterator i;
3107         boost::shared_ptr<Source> source;
3108
3109         if ((i = audio_sources.find (id)) != audio_sources.end()) {
3110                 source = i->second;
3111         }
3112
3113         /* XXX search MIDI or other searches here */
3114         
3115         return source;
3116 }
3117
3118
3119 boost::shared_ptr<Source>
3120 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3121 {
3122         Glib::Mutex::Lock lm (audio_source_lock);
3123
3124         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3125                 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3126
3127                 if (afs && afs->path() == path && chn == afs->channel()) {
3128                         return afs;
3129                 } 
3130                        
3131         }
3132         return boost::shared_ptr<Source>();
3133 }
3134
3135 Glib::ustring
3136 Session::peak_path (Glib::ustring base) const
3137 {
3138         return Glib::build_filename(peak_dir (), base + ".peak");
3139 }
3140
3141 string
3142 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3143 {
3144         string look_for;
3145         string old_basename = PBD::basename_nosuffix (oldname);
3146         string new_legalized = legalize_for_path (newname);
3147
3148         /* note: we know (or assume) the old path is already valid */
3149
3150         if (destructive) {
3151                 
3152                 /* destructive file sources have a name of the form:
3153
3154                     /path/to/Tnnnn-NAME(%[LR])?.wav
3155                   
3156                     the task here is to replace NAME with the new name.
3157                 */
3158                 
3159                 /* find last slash */
3160
3161                 string dir;
3162                 string prefix;
3163                 string::size_type slash;
3164                 string::size_type dash;
3165
3166                 if ((slash = path.find_last_of ('/')) == string::npos) {
3167                         return "";
3168                 }
3169
3170                 dir = path.substr (0, slash+1);
3171
3172                 /* '-' is not a legal character for the NAME part of the path */
3173
3174                 if ((dash = path.find_last_of ('-')) == string::npos) {
3175                         return "";
3176                 }
3177
3178                 prefix = path.substr (slash+1, dash-(slash+1));
3179
3180                 path = dir;
3181                 path += prefix;
3182                 path += '-';
3183                 path += new_legalized;
3184                 path += ".wav";  /* XXX gag me with a spoon */
3185                 
3186         } else {
3187                 
3188                 /* non-destructive file sources have a name of the form:
3189
3190                     /path/to/NAME-nnnnn(%[LR])?.wav
3191                   
3192                     the task here is to replace NAME with the new name.
3193                 */
3194                 
3195                 string dir;
3196                 string suffix;
3197                 string::size_type slash;
3198                 string::size_type dash;
3199                 string::size_type postfix;
3200
3201                 /* find last slash */
3202
3203                 if ((slash = path.find_last_of ('/')) == string::npos) {
3204                         return "";
3205                 }
3206
3207                 dir = path.substr (0, slash+1);
3208
3209                 /* '-' is not a legal character for the NAME part of the path */
3210
3211                 if ((dash = path.find_last_of ('-')) == string::npos) {
3212                         return "";
3213                 }
3214
3215                 suffix = path.substr (dash+1);
3216                 
3217                 // Suffix is now everything after the dash. Now we need to eliminate
3218                 // the nnnnn part, which is done by either finding a '%' or a '.'
3219
3220                 postfix = suffix.find_last_of ("%");
3221                 if (postfix == string::npos) {
3222                         postfix = suffix.find_last_of ('.');
3223                 }
3224
3225                 if (postfix != string::npos) {
3226                         suffix = suffix.substr (postfix);
3227                 } else {
3228                         error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3229                         return "";
3230                 }
3231
3232                 const uint32_t limit = 10000;
3233                 char buf[PATH_MAX+1];
3234
3235                 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3236
3237                         snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3238
3239                         if (access (buf, F_OK) != 0) {
3240                                 path = buf;
3241                                 break;
3242                         }
3243                         path = "";
3244                 }
3245
3246                 if (path == "") {
3247                         error << "FATAL ERROR! Could not find a " << endl;
3248                 }
3249
3250         }
3251
3252         return path;
3253 }
3254
3255 string
3256 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3257 {
3258         string spath;
3259         uint32_t cnt;
3260         char buf[PATH_MAX+1];
3261         const uint32_t limit = 10000;
3262         string legalized;
3263
3264         buf[0] = '\0';
3265         legalized = legalize_for_path (name);
3266
3267         /* find a "version" of the file name that doesn't exist in
3268            any of the possible directories.
3269         */
3270
3271         for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3272
3273                 vector<space_and_path>::iterator i;
3274                 uint32_t existing = 0;
3275
3276                 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3277
3278                         spath = (*i).path;
3279
3280                         spath += sound_dir (false);
3281
3282                         if (destructive) {
3283                                 if (nchan < 2) {
3284                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3285                                 } else if (nchan == 2) {
3286                                         if (chan == 0) {
3287                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3288                                         } else {
3289                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3290                                         }
3291                                 } else if (nchan < 26) {
3292                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3293                                 } else {
3294                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3295                                 }
3296
3297                         } else {
3298
3299                                 spath += '/';
3300                                 spath += legalized;
3301
3302                                 if (nchan < 2) {
3303                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3304                                 } else if (nchan == 2) {
3305                                         if (chan == 0) {
3306                                                 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3307                                         } else {
3308                                                 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3309                                         }
3310                                 } else if (nchan < 26) {
3311                                         snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3312                                 } else {
3313                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3314                                 }
3315                         }
3316
3317                         if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3318                                 existing++;
3319                         } 
3320
3321                 }
3322
3323                 if (existing == 0) {
3324                         break;
3325                 }
3326
3327                 if (cnt > limit) {
3328                         error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3329                         destroy ();
3330                         throw failed_constructor();
3331                 }
3332         }
3333
3334         /* we now have a unique name for the file, but figure out where to
3335            actually put it.
3336         */
3337
3338         string foo = buf;
3339
3340         spath = discover_best_sound_dir ();
3341         spath += '/';
3342
3343         string::size_type pos = foo.find_last_of ('/');
3344         
3345         if (pos == string::npos) {
3346                 spath += foo;
3347         } else {
3348                 spath += foo.substr (pos + 1);
3349         }
3350
3351         return spath;
3352 }
3353
3354 boost::shared_ptr<AudioFileSource>
3355 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3356 {
3357         string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3358         return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3359 }
3360
3361 /* Playlist management */
3362
3363 boost::shared_ptr<Playlist>
3364 Session::playlist_by_name (string name)
3365 {
3366         Glib::Mutex::Lock lm (playlist_lock);
3367         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3368                 if ((*i)->name() == name) {
3369                         return* i;
3370                 }
3371         }
3372         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3373                 if ((*i)->name() == name) {
3374                         return* i;
3375                 }
3376         }
3377
3378         return boost::shared_ptr<Playlist>();
3379 }
3380
3381 void
3382 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3383 {
3384         if (playlist->hidden()) {
3385                 return;
3386         }
3387
3388         { 
3389                 Glib::Mutex::Lock lm (playlist_lock);
3390                 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3391                         playlists.insert (playlists.begin(), playlist);
3392                         playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3393                         playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3394                 }
3395         }
3396
3397         set_dirty();
3398
3399         PlaylistAdded (playlist); /* EMIT SIGNAL */
3400 }
3401
3402 void
3403 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3404 {
3405         { 
3406                 Glib::Mutex::Lock lm (playlist_lock);
3407                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3408                         s.push_back (*i);
3409                 }
3410                 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3411                         s.push_back (*i);
3412                 }
3413         }
3414 }
3415
3416 void
3417 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3418 {
3419         boost::shared_ptr<Playlist> pl(wpl.lock());
3420
3421         if (!pl) {
3422                 return;
3423         }
3424
3425         PlaylistList::iterator x;
3426
3427         if (pl->hidden()) {
3428                 /* its not supposed to be visible */
3429                 return;
3430         }
3431
3432         { 
3433                 Glib::Mutex::Lock lm (playlist_lock);
3434
3435                 if (!inuse) {
3436
3437                         unused_playlists.insert (pl);
3438                         
3439                         if ((x = playlists.find (pl)) != playlists.end()) {
3440                                 playlists.erase (x);
3441                         }
3442
3443                         
3444                 } else {
3445
3446                         playlists.insert (pl);
3447                         
3448                         if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3449                                 unused_playlists.erase (x);
3450                         }
3451                 }
3452         }
3453 }
3454
3455 void
3456 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3457 {
3458         if (_state_of_the_state & Deletion) {
3459                 return;
3460         }
3461
3462         boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3463
3464         if (!playlist) {
3465                 return;
3466         }
3467
3468         { 
3469                 Glib::Mutex::Lock lm (playlist_lock);
3470
3471                 PlaylistList::iterator i;
3472
3473                 i = find (playlists.begin(), playlists.end(), playlist);
3474                 if (i != playlists.end()) {
3475                         playlists.erase (i);
3476                 }
3477
3478                 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3479                 if (i != unused_playlists.end()) {
3480                         unused_playlists.erase (i);
3481                 }
3482                 
3483         }
3484
3485         set_dirty();
3486
3487         PlaylistRemoved (playlist); /* EMIT SIGNAL */
3488 }
3489
3490 void 
3491 Session::set_audition (boost::shared_ptr<Region> r)
3492 {
3493         pending_audition_region = r;
3494         post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3495         schedule_butler_transport_work ();
3496 }
3497
3498 void
3499 Session::audition_playlist ()
3500 {
3501         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3502         ev->region.reset ();
3503         queue_event (ev);
3504 }
3505
3506 void
3507 Session::non_realtime_set_audition ()
3508 {
3509         if (!pending_audition_region) {
3510                 auditioner->audition_current_playlist ();
3511         } else {
3512                 auditioner->audition_region (pending_audition_region);
3513                 pending_audition_region.reset ();
3514         }
3515         AuditionActive (true); /* EMIT SIGNAL */
3516 }
3517
3518 void
3519 Session::audition_region (boost::shared_ptr<Region> r)
3520 {
3521         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3522         ev->region = r;
3523         queue_event (ev);
3524 }
3525
3526 void
3527 Session::cancel_audition ()
3528 {
3529         if (auditioner->active()) {
3530                 auditioner->cancel_audition ();
3531                 AuditionActive (false); /* EMIT SIGNAL */
3532         }
3533 }
3534
3535 bool
3536 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3537 {
3538         return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3539 }
3540
3541 void
3542 Session::remove_empty_sounds ()
3543 {
3544         PathScanner scanner;
3545
3546         vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3547         
3548         Glib::Mutex::Lock lm (audio_source_lock);
3549         
3550         regex_t compiled_tape_track_pattern;
3551         int err;
3552
3553         if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3554
3555                 char msg[256];
3556                 
3557                 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3558                 
3559                 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3560                 return;
3561         }
3562
3563         for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3564                 
3565                 /* never remove files that appear to be a tape track */
3566
3567                 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3568                         delete *i;
3569                         continue;
3570                 }
3571                         
3572                 if (AudioFileSource::is_empty (*this, **i)) {
3573
3574                         unlink ((*i)->c_str());
3575                         
3576                         Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3577                         unlink (peakpath.c_str());
3578                 }
3579
3580                 delete* i;
3581         }
3582
3583         delete possible_audiofiles;
3584 }
3585
3586 bool
3587 Session::is_auditioning () const
3588 {
3589         /* can be called before we have an auditioner object */
3590         if (auditioner) {
3591                 return auditioner->active();
3592         } else {
3593                 return false;
3594         }
3595 }
3596
3597 void
3598 Session::set_all_solo (bool yn)
3599 {
3600         shared_ptr<RouteList> r = routes.reader ();
3601
3602         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3603                 if (!(*i)->hidden()) {
3604                         (*i)->set_solo (yn, this);
3605                 }
3606         }
3607
3608         set_dirty();
3609 }
3610                 
3611 void
3612 Session::set_all_mute (bool yn)
3613 {
3614         shared_ptr<RouteList> r = routes.reader ();
3615         
3616         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3617                 if (!(*i)->hidden()) {
3618                         (*i)->set_mute (yn, this);
3619                 }
3620         }
3621
3622         set_dirty();
3623 }
3624                 
3625 uint32_t
3626 Session::n_diskstreams () const
3627 {
3628         uint32_t n = 0;
3629
3630         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3631
3632         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3633                 if (!(*i)->hidden()) {
3634                         n++;
3635                 }
3636         }
3637         return n;
3638 }
3639
3640 void
3641 Session::graph_reordered ()
3642 {
3643         /* don't do this stuff if we are setting up connections
3644            from a set_state() call or creating new tracks.
3645         */
3646
3647         if (_state_of_the_state & InitialConnecting) {
3648                 return;
3649         }
3650
3651         /* every track/bus asked for this to be handled but it was deferred because
3652            we were connecting. do it now.
3653         */
3654
3655         request_input_change_handling ();
3656
3657         resort_routes ();
3658
3659         /* force all diskstreams to update their capture offset values to 
3660            reflect any changes in latencies within the graph.
3661         */
3662         
3663         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3664
3665         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3666                 (*i)->set_capture_offset ();
3667         }
3668 }
3669
3670 void
3671 Session::record_disenable_all ()
3672 {
3673         record_enable_change_all (false);
3674 }
3675
3676 void
3677 Session::record_enable_all ()
3678 {
3679         record_enable_change_all (true);
3680 }
3681
3682 void
3683 Session::record_enable_change_all (bool yn)
3684 {
3685         shared_ptr<RouteList> r = routes.reader ();
3686         
3687         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3688                 AudioTrack* at;
3689
3690                 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3691                         at->set_record_enable (yn, this);
3692                 }
3693         }
3694         
3695         /* since we don't keep rec-enable state, don't mark session dirty */
3696 }
3697
3698 void
3699 Session::add_redirect (Redirect* redirect)
3700 {
3701         Send* send;
3702         Insert* insert;
3703         PortInsert* port_insert;
3704         PluginInsert* plugin_insert;
3705
3706         if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3707                 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3708                         _port_inserts.insert (_port_inserts.begin(), port_insert);
3709                 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3710                         _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3711                 } else {
3712                         fatal << _("programming error: unknown type of Insert created!") << endmsg;
3713                         /*NOTREACHED*/
3714                 }
3715         } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3716                 _sends.insert (_sends.begin(), send);
3717         } else {
3718                 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3719                 /*NOTREACHED*/
3720         }
3721
3722         redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3723
3724         set_dirty();
3725 }
3726
3727 void
3728 Session::remove_redirect (Redirect* redirect)
3729 {
3730         Send* send;
3731         Insert* insert;
3732         PortInsert* port_insert;
3733         PluginInsert* plugin_insert;
3734         
3735         if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3736                 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3737                         list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3738                         if (x != _port_inserts.end()) {
3739                                 insert_bitset[port_insert->bit_slot()] = false;
3740                                 _port_inserts.erase (x);
3741                         }
3742                 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3743                         _plugin_inserts.remove (plugin_insert);
3744                 } else {
3745                         fatal << string_compose (_("programming error: %1"),
3746                                                  X_("unknown type of Insert deleted!")) 
3747                               << endmsg;
3748                         /*NOTREACHED*/
3749                 }
3750         } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3751                 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3752                 if (x != _sends.end()) {
3753                         send_bitset[send->bit_slot()] = false;
3754                         _sends.erase (x);
3755                 }
3756         } else {
3757                 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3758                 /*NOTREACHED*/
3759         }
3760
3761         set_dirty();
3762 }
3763
3764 nframes_t
3765 Session::available_capture_duration ()
3766 {
3767         float sample_bytes_on_disk = 4.0; // keep gcc happy
3768
3769         switch (Config->get_native_file_data_format()) {
3770         case FormatFloat:
3771                 sample_bytes_on_disk = 4.0;
3772                 break;
3773
3774         case FormatInt24:
3775                 sample_bytes_on_disk = 3.0;
3776                 break;
3777
3778         case FormatInt16:
3779                 sample_bytes_on_disk = 2.0;
3780                 break;
3781
3782         default: 
3783                 /* impossible, but keep some gcc versions happy */
3784                 fatal << string_compose (_("programming error: %1"),
3785                                          X_("illegal native file data format"))
3786                       << endmsg;
3787                 /*NOTREACHED*/
3788         }
3789
3790         double scale = 4096.0 / sample_bytes_on_disk;
3791
3792         if (_total_free_4k_blocks * scale > (double) max_frames) {
3793                 return max_frames;
3794         }
3795         
3796         return (nframes_t) floor (_total_free_4k_blocks * scale);
3797 }
3798
3799 void
3800 Session::add_connection (ARDOUR::Connection* connection)
3801 {
3802         {
3803                 Glib::Mutex::Lock guard (connection_lock);
3804                 _connections.push_back (connection);
3805         }
3806         
3807         ConnectionAdded (connection); /* EMIT SIGNAL */
3808
3809         set_dirty();
3810 }
3811
3812 void
3813 Session::remove_connection (ARDOUR::Connection* connection)
3814 {
3815         bool removed = false;
3816
3817         {
3818                 Glib::Mutex::Lock guard (connection_lock);
3819                 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3820                 
3821                 if (i != _connections.end()) {
3822                         _connections.erase (i);
3823                         removed = true;
3824                 }
3825         }
3826
3827         if (removed) {
3828                  ConnectionRemoved (connection); /* EMIT SIGNAL */
3829         }
3830
3831         set_dirty();
3832 }
3833
3834 ARDOUR::Connection *
3835 Session::connection_by_name (string name) const
3836 {
3837         Glib::Mutex::Lock lm (connection_lock);
3838
3839         for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3840                 if ((*i)->name() == name) {
3841                         return* i;
3842                 }
3843         }
3844
3845         return 0;
3846 }
3847
3848 void
3849 Session::tempo_map_changed (Change ignored)
3850 {
3851         clear_clicks ();
3852         
3853         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3854                 (*i)->update_after_tempo_map_change ();
3855         }
3856
3857         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3858                 (*i)->update_after_tempo_map_change ();
3859         }
3860
3861         set_dirty ();
3862 }
3863
3864 void
3865 Session::ensure_passthru_buffers (uint32_t howmany)
3866 {
3867         if (current_block_size == 0) {
3868                 return;
3869         }
3870
3871         while (howmany > _passthru_buffers.size()) {
3872                 Sample *p;
3873 #ifdef NO_POSIX_MEMALIGN
3874                 p =  (Sample *) malloc(current_block_size * sizeof(Sample));
3875 #else
3876                 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3877                         fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3878                                                  current_block_size, sizeof (Sample), strerror (errno))
3879                               << endmsg;
3880                         /*NOTREACHED*/
3881                 }
3882 #endif                  
3883                 _passthru_buffers.push_back (p);
3884
3885                 *p = 0;
3886                 
3887 #ifdef NO_POSIX_MEMALIGN
3888                 p =  (Sample *) malloc(current_block_size * sizeof(Sample));
3889 #else
3890                 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3891                         fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3892                                                  current_block_size, sizeof (Sample), strerror (errno))
3893                               << endmsg;
3894                         /*NOTREACHED*/
3895                 }
3896 #endif                  
3897                 memset (p, 0, sizeof (Sample) * current_block_size);
3898                 _silent_buffers.push_back (p);
3899
3900                 *p = 0;
3901                 
3902 #ifdef NO_POSIX_MEMALIGN
3903                 p =  (Sample *) malloc(current_block_size * sizeof(Sample));
3904 #else
3905                 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3906 #endif                  
3907                 memset (p, 0, sizeof (Sample) * current_block_size);
3908                 _send_buffers.push_back (p);
3909                 
3910         }
3911         allocate_pan_automation_buffers (current_block_size, howmany, false);
3912 }
3913
3914 uint32_t
3915 Session::next_insert_id ()
3916 {
3917         /* this doesn't really loop forever. just think about it */
3918
3919         while (true) {
3920                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3921                         if (!insert_bitset[n]) {
3922                                 insert_bitset[n] = true;
3923                                 return n;
3924                                 
3925                         }
3926                 }
3927                 
3928                 /* none available, so resize and try again */
3929
3930                 insert_bitset.resize (insert_bitset.size() + 16, false);
3931         }
3932 }
3933
3934 uint32_t
3935 Session::next_send_id ()
3936 {
3937         /* this doesn't really loop forever. just think about it */
3938
3939         while (true) {
3940                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3941                         if (!send_bitset[n]) {
3942                                 send_bitset[n] = true;
3943                                 return n;
3944                                 
3945                         }
3946                 }
3947                 
3948                 /* none available, so resize and try again */
3949
3950                 send_bitset.resize (send_bitset.size() + 16, false);
3951         }
3952 }
3953
3954 void
3955 Session::mark_send_id (uint32_t id)
3956 {
3957         if (id >= send_bitset.size()) {
3958                 send_bitset.resize (id+16, false);
3959         }
3960         if (send_bitset[id]) {
3961                 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3962         }
3963         send_bitset[id] = true;
3964 }
3965
3966 void
3967 Session::mark_insert_id (uint32_t id)
3968 {
3969         if (id >= insert_bitset.size()) {
3970                 insert_bitset.resize (id+16, false);
3971         }
3972         if (insert_bitset[id]) {
3973                 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3974         }
3975         insert_bitset[id] = true;
3976 }
3977
3978 /* Named Selection management */
3979
3980 NamedSelection *
3981 Session::named_selection_by_name (string name)
3982 {
3983         Glib::Mutex::Lock lm (named_selection_lock);
3984         for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3985                 if ((*i)->name == name) {
3986                         return* i;
3987                 }
3988         }
3989         return 0;
3990 }
3991
3992 void
3993 Session::add_named_selection (NamedSelection* named_selection)
3994 {
3995         { 
3996                 Glib::Mutex::Lock lm (named_selection_lock);
3997                 named_selections.insert (named_selections.begin(), named_selection);
3998         }
3999
4000         for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4001                 add_playlist (*i);
4002         }
4003
4004         set_dirty();
4005
4006         NamedSelectionAdded (); /* EMIT SIGNAL */
4007 }
4008
4009 void
4010 Session::remove_named_selection (NamedSelection* named_selection)
4011 {
4012         bool removed = false;
4013
4014         { 
4015                 Glib::Mutex::Lock lm (named_selection_lock);
4016
4017                 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4018
4019                 if (i != named_selections.end()) {
4020                         delete (*i);
4021                         named_selections.erase (i);
4022                         set_dirty();
4023                         removed = true;
4024                 }
4025         }
4026
4027         if (removed) {
4028                  NamedSelectionRemoved (); /* EMIT SIGNAL */
4029         }
4030 }
4031
4032 void
4033 Session::reset_native_file_format ()
4034 {
4035         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4036
4037         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4038                 (*i)->reset_write_sources (false);
4039         }
4040 }
4041
4042 bool
4043 Session::route_name_unique (string n) const
4044 {
4045         shared_ptr<RouteList> r = routes.reader ();
4046         
4047         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4048                 if ((*i)->name() == n) {
4049                         return false;
4050                 }
4051         }
4052         
4053         return true;
4054 }
4055
4056 uint32_t
4057 Session::n_playlists () const
4058 {
4059         Glib::Mutex::Lock lm (playlist_lock);
4060         return playlists.size();
4061 }
4062
4063 void
4064 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4065 {
4066         if (!force && howmany <= _npan_buffers) {
4067                 return;
4068         }
4069
4070         if (_pan_automation_buffer) {
4071
4072                 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4073                         delete [] _pan_automation_buffer[i];
4074                 }
4075
4076                 delete [] _pan_automation_buffer;
4077         }
4078
4079         _pan_automation_buffer = new pan_t*[howmany];
4080         
4081         for (uint32_t i = 0; i < howmany; ++i) {
4082                 _pan_automation_buffer[i] = new pan_t[nframes];
4083         }
4084
4085         _npan_buffers = howmany;
4086 }
4087
4088 int
4089 Session::freeze (InterThreadInfo& itt)
4090 {
4091         shared_ptr<RouteList> r = routes.reader ();
4092
4093         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4094
4095                 AudioTrack *at;
4096
4097                 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4098                         /* XXX this is wrong because itt.progress will keep returning to zero at the start
4099                            of every track.
4100                         */
4101                         at->freeze (itt);
4102                 }
4103         }
4104
4105         return 0;
4106 }
4107
4108 boost::shared_ptr<Region>
4109 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,      
4110                                bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4111 {
4112         boost::shared_ptr<Region> result;
4113         boost::shared_ptr<Playlist> playlist;
4114         boost::shared_ptr<AudioFileSource> fsource;
4115         uint32_t x;
4116         char buf[PATH_MAX+1];
4117         string dir;
4118         uint32_t nchans;
4119         nframes_t position;
4120         nframes_t this_chunk;
4121         nframes_t to_do;
4122         nframes_t len = end - start;
4123         vector<Sample*> buffers;
4124
4125         if (end <= start) {
4126                 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4127                                          end, start) << endmsg;
4128                 return result;
4129         }
4130
4131         // any bigger than this seems to cause stack overflows in called functions
4132         const nframes_t chunk_size = (128 * 1024)/4;
4133
4134         // block all process callback handling
4135
4136         block_processing ();
4137         
4138         /* call tree *MUST* hold route_lock */
4139         
4140         if ((playlist = track.diskstream()->playlist()) == 0) {
4141                 goto out;
4142         }
4143
4144         /* external redirects will be a problem */
4145
4146         if (track.has_external_redirects()) {
4147                 goto out;
4148         }
4149
4150         nchans = track.audio_diskstream()->n_channels();
4151         
4152         dir = discover_best_sound_dir ();
4153
4154         for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4155
4156                 for (x = 0; x < 99999; ++x) {
4157                         snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4158                         if (access (buf, F_OK) != 0) {
4159                                 break;
4160                         }
4161                 }
4162                 
4163                 if (x == 99999) {
4164                         error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4165                         goto out;
4166                 }
4167                 
4168                 try {
4169                         fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4170                 }
4171                 
4172                 catch (failed_constructor& err) {
4173                         error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4174                         goto out;
4175                 }
4176
4177                 srcs.push_back (fsource);
4178         }
4179
4180         /* XXX need to flush all redirects */
4181         
4182         position = start;
4183         to_do = len;
4184
4185         /* create a set of reasonably-sized buffers */
4186
4187         for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4188                 Sample* b;
4189 #ifdef NO_POSIX_MEMALIGN
4190                 b =  (Sample *) malloc(chunk_size * sizeof(Sample));
4191 #else
4192                 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4193 #endif                  
4194                 buffers.push_back (b);
4195         }
4196
4197         for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4198                 (*src)->prepare_for_peakfile_writes ();
4199         }
4200                         
4201         while (to_do && !itt.cancel) {
4202                 
4203                 this_chunk = min (to_do, chunk_size);
4204                 
4205                 if (track.export_stuff (buffers, nchans, start, this_chunk, enable_processing)) {
4206                         goto out;
4207                 }
4208
4209                 uint32_t n = 0;
4210                 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4211                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4212                         
4213                         if (afs) {
4214                                 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4215                                         goto out;
4216                                 }
4217                         }
4218                 }
4219                 
4220                 start += this_chunk;
4221                 to_do -= this_chunk;
4222                 
4223                 itt.progress = (float) (1.0 - ((double) to_do / len));
4224
4225         }
4226
4227         if (!itt.cancel) {
4228                 
4229                 time_t now;
4230                 struct tm* xnow;
4231                 time (&now);
4232                 xnow = localtime (&now);
4233                 
4234                 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4235                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4236
4237                         if (afs) {
4238                                 afs->update_header (position, *xnow, now);
4239                                 afs->flush_header ();
4240                         }
4241                 }
4242                 
4243                 /* construct a region to represent the bounced material */
4244
4245                 result = RegionFactory::create (srcs, 0, srcs.front()->length(), 
4246                                                 region_name_from_path (srcs.front()->name(), true));
4247         }
4248                 
4249   out:
4250         if (!result) {
4251                 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4252                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4253
4254                         if (afs) {
4255                                 afs->mark_for_remove ();
4256                         }
4257                         
4258                         (*src)->drop_references ();
4259                 }
4260
4261         } else {
4262                 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4263                         (*src)->done_with_peakfile_writes ();
4264                 }
4265         }
4266
4267         for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4268                 free (*i);
4269         }
4270
4271         unblock_processing ();
4272
4273         itt.done = true;
4274
4275         return result;
4276 }
4277
4278 vector<Sample*>&
4279 Session::get_silent_buffers (uint32_t howmany)
4280 {
4281         if (howmany > _silent_buffers.size()) {
4282
4283                 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4284                                          howmany, _silent_buffers.size()) << endmsg;
4285
4286                 if (howmany > 1000) {
4287                         cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4288                         abort ();
4289                 }
4290                 
4291                 while (howmany > _silent_buffers.size()) {
4292                         Sample *p = 0;
4293                         
4294 #ifdef NO_POSIX_MEMALIGN
4295                         p =  (Sample *) malloc(current_block_size * sizeof(Sample));
4296 #else
4297                         if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4298                                 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4299                                                          current_block_size, sizeof (Sample), strerror (errno))
4300                                       << endmsg;
4301                                 /*NOTREACHED*/
4302                         }
4303 #endif                  
4304                         _silent_buffers.push_back (p);
4305                 }
4306         }
4307
4308         for (uint32_t i = 0; i < howmany; ++i) {
4309                 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4310         }
4311
4312         return _silent_buffers;
4313 }
4314
4315 uint32_t 
4316 Session::ntracks () const
4317 {
4318         uint32_t n = 0;
4319         shared_ptr<RouteList> r = routes.reader ();
4320
4321         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4322                 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4323                         ++n;
4324                 }
4325         }
4326
4327         return n;
4328 }
4329
4330 uint32_t 
4331 Session::nbusses () const
4332 {
4333         uint32_t n = 0;
4334         shared_ptr<RouteList> r = routes.reader ();
4335
4336         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4337                 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4338                         ++n;
4339                 }
4340         }
4341
4342         return n;
4343 }
4344
4345 void
4346 Session::add_automation_list(AutomationList *al)
4347 {
4348         automation_lists[al->id()] = al;
4349 }
4350
4351 nframes_t
4352 Session::compute_initial_length ()
4353 {
4354         return _engine.frame_rate() * 60 * 5;
4355 }
4356
4357 void
4358 Session::sync_order_keys (const char* base)
4359 {
4360         if (!Config->get_sync_all_route_ordering()) {
4361                 /* leave order keys as they are */
4362                 return;
4363         }
4364
4365         boost::shared_ptr<RouteList> r = routes.reader ();
4366
4367         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4368                 (*i)->sync_order_keys (base);
4369         }
4370
4371         Route::SyncOrderKeys (base); // EMIT SIGNAL
4372 }