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