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