d3b65210a405c65e196de60180e8b22412c8d899
[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                 vector<string> cports;
919
920                 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
921                         if (_control_out->add_input_port ("", this)) {
922                                 error << _("cannot setup control inputs")
923                                       << endmsg;
924                                 break;
925                         }
926                 }
927                 n = 0;
928                 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
929                         if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
930                                 error << _("cannot set up master outputs")
931                                       << endmsg;
932                                 break;
933                         }
934                         n++;
935                 }
936
937
938                 uint32_t ni = _control_out->n_inputs();
939
940                 for (n = 0; n < ni; ++n) {
941                         cports.push_back (_control_out->input(n)->name());
942                 }
943
944                 boost::shared_ptr<RouteList> r = routes.reader ();              
945
946                 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
947                         (*x)->set_control_outs (cports);
948                 }
949         } 
950
951         /* Tell all IO objects to connect themselves together */
952
953         IO::enable_connecting ();
954
955         /* Now reset all panners */
956
957         IO::reset_panners ();
958
959         /* Anyone who cares about input state, wake up and do something */
960
961         IOConnectionsComplete (); /* EMIT SIGNAL */
962
963         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
964
965         /* now handle the whole enchilada as if it was one
966            graph reorder event.
967         */
968
969         graph_reordered ();
970
971         /* update mixer solo state */
972
973         catch_up_on_solo();
974 }
975
976 void
977 Session::playlist_length_changed ()
978 {
979         /* we can't just increase end_location->end() if pl->get_maximum_extent() 
980            if larger. if the playlist used to be the longest playlist,
981            and its now shorter, we have to decrease end_location->end(). hence,
982            we have to iterate over all diskstreams and check the 
983            playlists currently in use.
984         */
985         find_current_end ();
986 }
987
988 void
989 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
990 {
991         boost::shared_ptr<Playlist> playlist;
992
993         if ((playlist = dstream->playlist()) != 0) {
994                 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
995         }
996         
997         /* see comment in playlist_length_changed () */
998         find_current_end ();
999 }
1000
1001 bool
1002 Session::record_enabling_legal () const
1003 {
1004         /* this used to be in here, but survey says.... we don't need to restrict it */
1005         // if (record_status() == Recording) {
1006         //      return false;
1007         // }
1008
1009         if (Config->get_all_safe()) {
1010                 return false;
1011         }
1012         return true;
1013 }
1014
1015 void
1016 Session::reset_input_monitor_state ()
1017 {
1018         if (transport_rolling()) {
1019
1020                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1021
1022                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1023                         if ((*i)->record_enabled ()) {
1024                                 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1025                                 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1026                         }
1027                 }
1028         } else {
1029                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1030
1031                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1032                         if ((*i)->record_enabled ()) {
1033                                 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1034                                 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1035                         }
1036                 }
1037         }
1038 }
1039
1040 void
1041 Session::auto_punch_start_changed (Location* location)
1042 {
1043         replace_event (Event::PunchIn, location->start());
1044
1045         if (get_record_enabled() && Config->get_punch_in()) {
1046                 /* capture start has been changed, so save new pending state */
1047                 save_state ("", true);
1048         }
1049 }       
1050
1051 void
1052 Session::auto_punch_end_changed (Location* location)
1053 {
1054         nframes_t when_to_stop = location->end();
1055         // when_to_stop += _worst_output_latency + _worst_input_latency;
1056         replace_event (Event::PunchOut, when_to_stop);
1057 }       
1058
1059 void
1060 Session::auto_punch_changed (Location* location)
1061 {
1062         nframes_t when_to_stop = location->end();
1063
1064         replace_event (Event::PunchIn, location->start());
1065         //when_to_stop += _worst_output_latency + _worst_input_latency;
1066         replace_event (Event::PunchOut, when_to_stop);
1067 }       
1068
1069 void
1070 Session::auto_loop_changed (Location* location)
1071 {
1072         replace_event (Event::AutoLoop, location->end(), location->start());
1073
1074         if (transport_rolling() && play_loop) {
1075
1076                 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1077
1078                 if (_transport_frame > location->end()) {
1079                         // relocate to beginning of loop
1080                         clear_events (Event::LocateRoll);
1081                         
1082                         request_locate (location->start(), true);
1083
1084                 }
1085                 else if (Config->get_seamless_loop() && !loop_changing) {
1086                         
1087                         // schedule a locate-roll to refill the diskstreams at the
1088                         // previous loop end
1089                         loop_changing = true;
1090
1091                         if (location->end() > last_loopend) {
1092                                 clear_events (Event::LocateRoll);
1093                                 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1094                                 queue_event (ev);
1095                         }
1096
1097                 }
1098         }       
1099
1100         last_loopend = location->end();
1101         
1102 }
1103
1104 void
1105 Session::set_auto_punch_location (Location* location)
1106 {
1107         Location* existing;
1108
1109         if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1110                 auto_punch_start_changed_connection.disconnect();
1111                 auto_punch_end_changed_connection.disconnect();
1112                 auto_punch_changed_connection.disconnect();
1113                 existing->set_auto_punch (false, this);
1114                 remove_event (existing->start(), Event::PunchIn);
1115                 clear_events (Event::PunchOut);
1116                 auto_punch_location_changed (0);
1117         }
1118
1119         set_dirty();
1120
1121         if (location == 0) {
1122                 return;
1123         }
1124         
1125         if (location->end() <= location->start()) {
1126                 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1127                 return;
1128         }
1129
1130         auto_punch_start_changed_connection.disconnect();
1131         auto_punch_end_changed_connection.disconnect();
1132         auto_punch_changed_connection.disconnect();
1133                 
1134         auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1135         auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1136         auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1137
1138         location->set_auto_punch (true, this);
1139         auto_punch_location_changed (location);
1140 }
1141
1142 void
1143 Session::set_auto_loop_location (Location* location)
1144 {
1145         Location* existing;
1146
1147         if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1148                 auto_loop_start_changed_connection.disconnect();
1149                 auto_loop_end_changed_connection.disconnect();
1150                 auto_loop_changed_connection.disconnect();
1151                 existing->set_auto_loop (false, this);
1152                 remove_event (existing->end(), Event::AutoLoop);
1153                 auto_loop_location_changed (0);
1154         }
1155         
1156         set_dirty();
1157
1158         if (location == 0) {
1159                 return;
1160         }
1161
1162         if (location->end() <= location->start()) {
1163                 error << _("Session: you can't use a mark for auto loop") << endmsg;
1164                 return;
1165         }
1166
1167         last_loopend = location->end();
1168         
1169         auto_loop_start_changed_connection.disconnect();
1170         auto_loop_end_changed_connection.disconnect();
1171         auto_loop_changed_connection.disconnect();
1172         
1173         auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1174         auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1175         auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1176
1177         location->set_auto_loop (true, this);
1178         auto_loop_location_changed (location);
1179 }
1180
1181 void
1182 Session::locations_added (Location* ignored)
1183 {
1184         set_dirty ();
1185 }
1186
1187 void
1188 Session::locations_changed ()
1189 {
1190         _locations.apply (*this, &Session::handle_locations_changed);
1191 }
1192
1193 void
1194 Session::handle_locations_changed (Locations::LocationList& locations)
1195 {
1196         Locations::LocationList::iterator i;
1197         Location* location;
1198         bool set_loop = false;
1199         bool set_punch = false;
1200
1201         for (i = locations.begin(); i != locations.end(); ++i) {
1202
1203                 location =* i;
1204
1205                 if (location->is_auto_punch()) {
1206                         set_auto_punch_location (location);
1207                         set_punch = true;
1208                 }
1209                 if (location->is_auto_loop()) {
1210                         set_auto_loop_location (location);
1211                         set_loop = true;
1212                 }
1213                 
1214         }
1215
1216         if (!set_loop) {
1217                 set_auto_loop_location (0);
1218         }
1219         if (!set_punch) {
1220                 set_auto_punch_location (0);
1221         }
1222
1223         set_dirty();
1224 }                                                    
1225
1226 void
1227 Session::enable_record ()
1228 {
1229         /* XXX really atomic compare+swap here */
1230         if (g_atomic_int_get (&_record_status) != Recording) {
1231                 g_atomic_int_set (&_record_status, Recording);
1232                 _last_record_location = _transport_frame;
1233                 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1234
1235                 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1236                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1237                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1238                                 if ((*i)->record_enabled ()) {
1239                                         (*i)->monitor_input (true);   
1240                                 }
1241                         }
1242                 }
1243
1244                 RecordStateChanged ();
1245         }
1246 }
1247
1248 void
1249 Session::disable_record (bool rt_context, bool force)
1250 {
1251         RecordState rs;
1252
1253         if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1254
1255                 if (!Config->get_latched_record_enable () || force) {
1256                         g_atomic_int_set (&_record_status, Disabled);
1257                 } else {
1258                         if (rs == Recording) {
1259                                 g_atomic_int_set (&_record_status, Enabled);
1260                         }
1261                 }
1262
1263                 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1264
1265                 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1266                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1267                         
1268                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1269                                 if ((*i)->record_enabled ()) {
1270                                         (*i)->monitor_input (false);   
1271                                 }
1272                         }
1273                 }
1274                 
1275                 RecordStateChanged (); /* emit signal */
1276
1277                 if (!rt_context) {
1278                         remove_pending_capture_state ();
1279                 }
1280         }
1281 }
1282
1283 void
1284 Session::step_back_from_record ()
1285 {
1286         g_atomic_int_set (&_record_status, Enabled);
1287
1288         if (Config->get_monitoring_model() == HardwareMonitoring) {
1289                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1290                 
1291                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1292                         if (Config->get_auto_input() && (*i)->record_enabled ()) {
1293                                 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1294                                 (*i)->monitor_input (false);   
1295                         }
1296                 }
1297         }
1298 }
1299
1300 void
1301 Session::maybe_enable_record ()
1302 {
1303         g_atomic_int_set (&_record_status, Enabled);
1304
1305         /* this function is currently called from somewhere other than an RT thread.
1306            this save_state() call therefore doesn't impact anything.
1307         */
1308
1309         save_state ("", true);
1310
1311         if (_transport_speed) {
1312                 if (!Config->get_punch_in()) {
1313                         enable_record ();
1314                 } 
1315         } else {
1316                 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1317                 RecordStateChanged (); /* EMIT SIGNAL */
1318         }
1319
1320         set_dirty();
1321 }
1322
1323 nframes_t
1324 Session::audible_frame () const
1325 {
1326         nframes_t ret;
1327         nframes_t offset;
1328         nframes_t tf;
1329
1330         /* the first of these two possible settings for "offset"
1331            mean that the audible frame is stationary until 
1332            audio emerges from the latency compensation
1333            "pseudo-pipeline".
1334
1335            the second means that the audible frame is stationary
1336            until audio would emerge from a physical port
1337            in the absence of any plugin latency compensation
1338         */
1339
1340         offset = _worst_output_latency;
1341
1342         if (offset > current_block_size) {
1343                 offset -= current_block_size;
1344         } else { 
1345                 /* XXX is this correct? if we have no external
1346                    physical connections and everything is internal
1347                    then surely this is zero? still, how
1348                    likely is that anyway?
1349                 */
1350                 offset = current_block_size;
1351         }
1352
1353         if (synced_to_jack()) {
1354                 tf = _engine.transport_frame();
1355         } else {
1356                 tf = _transport_frame;
1357         }
1358
1359         if (_transport_speed == 0) {
1360                 return tf;
1361         }
1362
1363         if (tf < offset) {
1364                 return 0;
1365         }
1366
1367         ret = tf;
1368
1369         if (!non_realtime_work_pending()) {
1370
1371                 /* MOVING */
1372
1373                 /* take latency into account */
1374                 
1375                 ret -= offset;
1376         }
1377
1378         return ret;
1379 }
1380
1381 void
1382 Session::set_frame_rate (nframes_t frames_per_second)
1383 {
1384         /** \fn void Session::set_frame_size(nframes_t)
1385                 the AudioEngine object that calls this guarantees 
1386                 that it will not be called while we are also in
1387                 ::process(). Its fine to do things that block
1388                 here.
1389         */
1390
1391         _base_frame_rate = frames_per_second;
1392
1393         sync_time_vars();
1394
1395         Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1396
1397         // XXX we need some equivalent to this, somehow
1398         // SndFileSource::setup_standard_crossfades (frames_per_second);
1399
1400         set_dirty();
1401
1402         /* XXX need to reset/reinstantiate all LADSPA plugins */
1403 }
1404
1405 void
1406 Session::set_block_size (nframes_t nframes)
1407 {
1408         /* the AudioEngine guarantees 
1409            that it will not be called while we are also in
1410            ::process(). It is therefore fine to do things that block
1411            here.
1412         */
1413
1414         { 
1415                 vector<Sample*>::iterator i;
1416                 uint32_t np;
1417                         
1418                 current_block_size = nframes;
1419
1420                 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1421                         free (*i);
1422                 }
1423
1424                 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1425                         free (*i);
1426                 }
1427
1428                 _passthru_buffers.clear ();
1429                 _silent_buffers.clear ();
1430
1431                 ensure_passthru_buffers (np);
1432
1433                 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1434                         free(*i);
1435
1436                         Sample *buf;
1437 #ifdef NO_POSIX_MEMALIGN
1438                         buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1439 #else
1440                         posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1441 #endif                  
1442                         *i = buf;
1443
1444                         memset (*i, 0, sizeof (Sample) * current_block_size);
1445                 }
1446
1447                 
1448                 if (_gain_automation_buffer) {
1449                         delete [] _gain_automation_buffer;
1450                 }
1451                 _gain_automation_buffer = new gain_t[nframes];
1452
1453                 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1454
1455                 boost::shared_ptr<RouteList> r = routes.reader ();
1456
1457                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1458                         (*i)->set_block_size (nframes);
1459                 }
1460                 
1461                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1462                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1463                         (*i)->set_block_size (nframes);
1464                 }
1465
1466                 set_worst_io_latencies ();
1467         }
1468 }
1469
1470 void
1471 Session::set_default_fade (float steepness, float fade_msecs)
1472 {
1473 #if 0
1474         nframes_t fade_frames;
1475         
1476         /* Don't allow fade of less 1 frame */
1477         
1478         if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1479
1480                 fade_msecs = 0;
1481                 fade_frames = 0;
1482
1483         } else {
1484                 
1485                 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1486                 
1487         }
1488
1489         default_fade_msecs = fade_msecs;
1490         default_fade_steepness = steepness;
1491
1492         {
1493                 // jlc, WTF is this!
1494                 Glib::RWLock::ReaderLock lm (route_lock);
1495                 AudioRegion::set_default_fade (steepness, fade_frames);
1496         }
1497
1498         set_dirty();
1499
1500         /* XXX have to do this at some point */
1501         /* foreach region using default fade, reset, then 
1502            refill_all_diskstream_buffers ();
1503         */
1504 #endif
1505 }
1506
1507 struct RouteSorter {
1508     bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1509             if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1510                     return false;
1511             } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1512                     return true;
1513             } else {
1514                     if (r1->fed_by.empty()) {
1515                             if (r2->fed_by.empty()) {
1516                                     /* no ardour-based connections inbound to either route. just use signal order */
1517                                     return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1518                             } else {
1519                                     /* r2 has connections, r1 does not; run r1 early */
1520                                     return true;
1521                             }
1522                     } else {
1523                             return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1524                     }
1525             }
1526     }
1527 };
1528
1529 static void
1530 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1531 {
1532         shared_ptr<Route> r2;
1533
1534         if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1535                 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1536                 return;
1537         } 
1538
1539         /* make a copy of the existing list of routes that feed r1 */
1540
1541         set<shared_ptr<Route> > existing = r1->fed_by;
1542
1543         /* for each route that feeds r1, recurse, marking it as feeding
1544            rbase as well.
1545         */
1546
1547         for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1548                 r2 =* i;
1549
1550                 /* r2 is a route that feeds r1 which somehow feeds base. mark
1551                    base as being fed by r2
1552                 */
1553
1554                 rbase->fed_by.insert (r2);
1555
1556                 if (r2 != rbase) {
1557
1558                         /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1559                            stop here.
1560                          */
1561
1562                         if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1563                                 continue;
1564                         }
1565
1566                         /* now recurse, so that we can mark base as being fed by
1567                            all routes that feed r2
1568                         */
1569
1570                         trace_terminal (r2, rbase);
1571                 }
1572
1573         }
1574 }
1575
1576 void
1577 Session::resort_routes ()
1578 {
1579         /* don't do anything here with signals emitted
1580            by Routes while we are being destroyed.
1581         */
1582
1583         if (_state_of_the_state & Deletion) {
1584                 return;
1585         }
1586
1587
1588         {
1589
1590                 RCUWriter<RouteList> writer (routes);
1591                 shared_ptr<RouteList> r = writer.get_copy ();
1592                 resort_routes_using (r);
1593                 /* writer goes out of scope and forces update */
1594         }
1595
1596 }
1597 void
1598 Session::resort_routes_using (shared_ptr<RouteList> r)
1599 {
1600         RouteList::iterator i, j;
1601         
1602         for (i = r->begin(); i != r->end(); ++i) {
1603                 
1604                 (*i)->fed_by.clear ();
1605                 
1606                 for (j = r->begin(); j != r->end(); ++j) {
1607                         
1608                         /* although routes can feed themselves, it will
1609                            cause an endless recursive descent if we
1610                            detect it. so don't bother checking for
1611                            self-feeding.
1612                         */
1613                         
1614                         if (*j == *i) {
1615                                 continue;
1616                         }
1617                         
1618                         if ((*j)->feeds (*i)) {
1619                                 (*i)->fed_by.insert (*j);
1620                         } 
1621                 }
1622         }
1623         
1624         for (i = r->begin(); i != r->end(); ++i) {
1625                 trace_terminal (*i, *i);
1626         }       
1627
1628         RouteSorter cmp;
1629         r->sort (cmp);
1630         
1631         /* don't leave dangling references to routes in Route::fed_by */
1632
1633         for (i = r->begin(); i != r->end(); ++i) {
1634                 (*i)->fed_by.clear ();
1635         }
1636
1637 #if 0
1638         cerr << "finished route resort\n";
1639         
1640         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1641                 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1642         }
1643         cerr << endl;
1644 #endif
1645         
1646 }
1647
1648 list<boost::shared_ptr<AudioTrack> >
1649 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1650 {
1651         char track_name[32];
1652         uint32_t track_id = 0;
1653         uint32_t n = 0;
1654         uint32_t channels_used = 0;
1655         string port;
1656         RouteList new_routes;
1657         list<boost::shared_ptr<AudioTrack> > ret;
1658         uint32_t control_id;
1659
1660         /* count existing audio tracks */
1661
1662         {
1663                 shared_ptr<RouteList> r = routes.reader ();
1664
1665                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1666                         if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1667                                 if (!(*i)->hidden()) {
1668                                         n++;
1669                                         channels_used += (*i)->n_inputs();
1670                                 }
1671                         }
1672                 }
1673         }
1674
1675         vector<string> physinputs;
1676         vector<string> physoutputs;
1677         uint32_t nphysical_in;
1678         uint32_t nphysical_out;
1679
1680         _engine.get_physical_outputs (physoutputs);
1681         _engine.get_physical_inputs (physinputs);
1682         control_id = ntracks() + nbusses() + 1;
1683
1684         while (how_many) {
1685
1686                 /* check for duplicate route names, since we might have pre-existing
1687                    routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1688                    save, close,restart,add new route - first named route is now
1689                    Audio2)
1690                 */
1691                 
1692
1693                 do {
1694                         ++track_id;
1695
1696                         snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1697
1698                         if (route_by_name (track_name) == 0) {
1699                                 break;
1700                         }
1701                         
1702                 } while (track_id < (UINT_MAX-1));
1703
1704                 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1705                         nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1706                 } else {
1707                         nphysical_in = 0;
1708                 }
1709                 
1710                 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1711                         nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1712                 } else {
1713                         nphysical_out = 0;
1714                 }
1715
1716                 shared_ptr<AudioTrack> track;
1717                 
1718                 try {
1719                         track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1720                         
1721                         if (track->ensure_io (input_channels, output_channels, false, this)) {
1722                                 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1723                                                          input_channels, output_channels)
1724                                       << endmsg;
1725                                 goto failed;
1726                         }
1727
1728                         if (nphysical_in) {
1729                                 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1730                                         
1731                                         port = "";
1732                                         
1733                                         if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1734                                                 port = physinputs[(channels_used+x)%nphysical_in];
1735                                         } 
1736                                         
1737                                         if (port.length() && track->connect_input (track->input (x), port, this)) {
1738                                                 break;
1739                                         }
1740                                 }
1741                         }
1742                         
1743                         for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1744                                 
1745                                 port = "";
1746                                 
1747                                 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1748                                         port = physoutputs[(channels_used+x)%nphysical_out];
1749                                 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1750                                         if (_master_out) {
1751                                                 port = _master_out->input (x%_master_out->n_inputs())->name();
1752                                         }
1753                                 }
1754                                 
1755                                 if (port.length() && track->connect_output (track->output (x), port, this)) {
1756                                         break;
1757                                 }
1758                         }
1759                         
1760                         channels_used += track->n_inputs ();
1761
1762                         track->audio_diskstream()->non_realtime_input_change();
1763                         
1764                         track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1765                         track->set_remote_control_id (control_id);
1766                         ++control_id;
1767
1768                         new_routes.push_back (track);
1769                         ret.push_back (track);
1770                 }
1771
1772                 catch (failed_constructor &err) {
1773                         error << _("Session: could not create new audio track.") << endmsg;
1774
1775                         if (track) {
1776                                 /* we need to get rid of this, since the track failed to be created */
1777                                 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1778
1779                                 { 
1780                                         RCUWriter<DiskstreamList> writer (diskstreams);
1781                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1782                                         ds->remove (track->audio_diskstream());
1783                                 }
1784                         }
1785
1786                         goto failed;
1787                 }
1788
1789                 catch (AudioEngine::PortRegistrationFailure& pfe) {
1790
1791                         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;
1792
1793                         if (track) {
1794                                 /* we need to get rid of this, since the track failed to be created */
1795                                 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1796
1797                                 { 
1798                                         RCUWriter<DiskstreamList> writer (diskstreams);
1799                                         boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1800                                         ds->remove (track->audio_diskstream());
1801                                 }
1802                         }
1803
1804                         goto failed;
1805                 }
1806
1807                 --how_many;
1808         }
1809
1810   failed:
1811         if (!new_routes.empty()) {
1812                 add_routes (new_routes, false);
1813                 save_state (_current_snapshot_name);
1814         }
1815
1816         return ret;
1817 }
1818
1819 void
1820 Session::set_remote_control_ids ()
1821 {
1822         RemoteModel m = Config->get_remote_model();
1823
1824         shared_ptr<RouteList> r = routes.reader ();
1825
1826         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1827                 if ( MixerOrdered == m) {                       
1828                         long order = (*i)->order_key(N_("signal"));
1829                         (*i)->set_remote_control_id( order+1 );
1830                 } else if ( EditorOrdered == m) {
1831                         long order = (*i)->order_key(N_("editor"));
1832                         (*i)->set_remote_control_id( order+1 );
1833                 } else if ( UserOrdered == m) {
1834                         //do nothing ... only changes to remote id's are initiated by user 
1835                 }
1836         }
1837 }
1838
1839
1840 Session::RouteList
1841 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1842 {
1843         char bus_name[32];
1844         uint32_t bus_id = 1;
1845         uint32_t n = 0;
1846         string port;
1847         RouteList ret;
1848         uint32_t control_id;
1849
1850         /* count existing audio busses */
1851
1852         {
1853                 shared_ptr<RouteList> r = routes.reader ();
1854
1855                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1856                         if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1857                                 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1858                                         bus_id++;
1859                                 }
1860                         }
1861                 }
1862         }
1863
1864         vector<string> physinputs;
1865         vector<string> physoutputs;
1866
1867         _engine.get_physical_outputs (physoutputs);
1868         _engine.get_physical_inputs (physinputs);
1869         control_id = ntracks() + nbusses() + 1;
1870
1871         while (how_many) {
1872
1873                 do {
1874                         snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1875
1876                         bus_id++;
1877
1878                         if (route_by_name (bus_name) == 0) {
1879                                 break;
1880                         }
1881
1882                 } while (bus_id < (UINT_MAX-1));
1883
1884                 try {
1885                         shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1886                         
1887                         if (bus->ensure_io (input_channels, output_channels, false, this)) {
1888                                 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1889                                                          input_channels, output_channels)
1890                                       << endmsg;
1891                                 goto failure;
1892                         }
1893                         
1894                         for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1895                                 
1896                                 port = "";
1897
1898                                 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1899                                                 port = physinputs[((n+x)%n_physical_inputs)];
1900                                 } 
1901                                 
1902                                 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1903                                         break;
1904                                 }
1905                         }
1906                         
1907                         for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1908                                 
1909                                 port = "";
1910                                 
1911                                 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1912                                         port = physoutputs[((n+x)%n_physical_outputs)];
1913                                 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1914                                         if (_master_out) {
1915                                                 port = _master_out->input (x%_master_out->n_inputs())->name();
1916                                         }
1917                                 }
1918                                 
1919                                 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1920                                         break;
1921                                 }
1922                         }
1923                         
1924                         bus->set_remote_control_id (control_id);
1925                         ++control_id;
1926
1927                         ret.push_back (bus);
1928                 }
1929         
1930
1931                 catch (failed_constructor &err) {
1932                         error << _("Session: could not create new audio route.") << endmsg;
1933                         goto failure;
1934                 }
1935
1936                 catch (AudioEngine::PortRegistrationFailure& pfe) {
1937                         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;
1938                         goto failure;
1939                 }
1940
1941
1942                 --how_many;
1943         }
1944
1945   failure:
1946         if (!ret.empty()) {
1947                 add_routes (ret, false);
1948                 save_state (_current_snapshot_name);
1949         }
1950
1951         return ret;
1952
1953 }
1954
1955 void
1956 Session::add_routes (RouteList& new_routes, bool save)
1957 {
1958         { 
1959                 RCUWriter<RouteList> writer (routes);
1960                 shared_ptr<RouteList> r = writer.get_copy ();
1961                 r->insert (r->end(), new_routes.begin(), new_routes.end());
1962                 resort_routes_using (r);
1963         }
1964
1965         for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1966                 
1967                 boost::weak_ptr<Route> wpr (*x);
1968
1969                 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1970                 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1971                 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1972                 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1973                 
1974                 if ((*x)->master()) {
1975                         _master_out = (*x);
1976                 }
1977                 
1978                 if ((*x)->control()) {
1979                         _control_out = (*x);
1980                 } 
1981         }
1982
1983         if (_control_out && IO::connecting_legal) {
1984
1985                 vector<string> cports;
1986                 uint32_t ni = _control_out->n_inputs();
1987                 uint32_t n;
1988
1989                 for (n = 0; n < ni; ++n) {
1990                         cports.push_back (_control_out->input(n)->name());
1991                 }
1992
1993                 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1994                         (*x)->set_control_outs (cports);
1995                 }
1996         } 
1997
1998         set_dirty();
1999
2000         if (save) {
2001                 save_state (_current_snapshot_name);
2002         }
2003
2004         RouteAdded (new_routes); /* EMIT SIGNAL */
2005 }
2006
2007 void
2008 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2009 {
2010         /* need to do this in case we're rolling at the time, to prevent false underruns */
2011         dstream->do_refill_with_alloc ();
2012         
2013         dstream->set_block_size (current_block_size);
2014
2015         {
2016                 RCUWriter<DiskstreamList> writer (diskstreams);
2017                 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2018                 ds->push_back (dstream);
2019                 /* writer goes out of scope, copies ds back to main */
2020         } 
2021
2022         dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2023         /* this will connect to future changes, and check the current length */
2024         diskstream_playlist_changed (dstream);
2025
2026         dstream->prepare ();
2027
2028 }
2029
2030 void
2031 Session::remove_route (shared_ptr<Route> route)
2032 {
2033         {       
2034                 RCUWriter<RouteList> writer (routes);
2035                 shared_ptr<RouteList> rs = writer.get_copy ();
2036                 
2037                 rs->remove (route);
2038
2039                 /* deleting the master out seems like a dumb
2040                    idea, but its more of a UI policy issue
2041                    than our concern.
2042                 */
2043
2044                 if (route == _master_out) {
2045                         _master_out = shared_ptr<Route> ();
2046                 }
2047
2048                 if (route == _control_out) {
2049                         _control_out = shared_ptr<Route> ();
2050
2051                         /* cancel control outs for all routes */
2052
2053                         vector<string> empty;
2054
2055                         for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2056                                 (*r)->set_control_outs (empty);
2057                         }
2058                 }
2059
2060                 update_route_solo_state ();
2061                 
2062                 /* writer goes out of scope, forces route list update */
2063         }
2064
2065         // FIXME: audio specific
2066         AudioTrack* at;
2067         boost::shared_ptr<AudioDiskstream> ds;
2068         
2069         if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2070                 ds = at->audio_diskstream();
2071         }
2072         
2073         if (ds) {
2074
2075                 {
2076                         RCUWriter<DiskstreamList> dsl (diskstreams);
2077                         boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2078                         d->remove (ds);
2079                 }
2080         }
2081
2082         find_current_end ();
2083         
2084         update_latency_compensation (false, false);
2085         set_dirty();
2086
2087         // We need to disconnect the routes inputs and outputs 
2088         route->disconnect_inputs(NULL);
2089         route->disconnect_outputs(NULL);
2090         
2091         /* get rid of it from the dead wood collection in the route list manager */
2092
2093         /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2094
2095         routes.flush ();
2096
2097         /* try to cause everyone to drop their references */
2098
2099         route->drop_references ();
2100
2101         /* save the new state of the world */
2102
2103         if (save_state (_current_snapshot_name)) {
2104                 save_history (_current_snapshot_name);
2105         }
2106 }       
2107
2108 void
2109 Session::route_mute_changed (void* src)
2110 {
2111         set_dirty ();
2112 }
2113
2114 void
2115 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2116 {      
2117         if (solo_update_disabled) {
2118                 // We know already
2119                 return;
2120         }
2121         
2122         bool is_track;
2123         boost::shared_ptr<Route> route = wpr.lock ();
2124
2125         if (!route) {
2126                 /* should not happen */
2127                 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2128                 return;
2129         }
2130
2131         is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2132         
2133         shared_ptr<RouteList> r = routes.reader ();
2134
2135         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2136                 
2137                 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2138                 
2139                 if (is_track) {
2140                         
2141                         /* don't mess with busses */
2142                         
2143                         if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2144                                 continue;
2145                         }
2146                         
2147                 } else {
2148                         
2149                         /* don't mess with tracks */
2150                         
2151                         if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2152                                 continue;
2153                         }
2154                 }
2155                 
2156                 if ((*i) != route &&
2157                     ((*i)->mix_group () == 0 ||
2158                      (*i)->mix_group () != route->mix_group () ||
2159                      !route->mix_group ()->is_active())) {
2160                         
2161                         if ((*i)->soloed()) {
2162                                 
2163                                 /* if its already soloed, and solo latching is enabled,
2164                                    then leave it as it is.
2165                                 */
2166                                 
2167                                 if (Config->get_solo_latched()) {
2168                                         continue;
2169                                 } 
2170                         }
2171                         
2172                         /* do it */
2173
2174                         solo_update_disabled = true;
2175                         (*i)->set_solo (false, src);
2176                         solo_update_disabled = false;
2177                 }
2178         }
2179         
2180         bool something_soloed = false;
2181         bool same_thing_soloed = false;
2182         bool signal = false;
2183
2184         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2185                 if ((*i)->soloed()) {
2186                         something_soloed = true;
2187                         if (dynamic_cast<AudioTrack*>((*i).get())) {
2188                                 if (is_track) {
2189                                         same_thing_soloed = true;
2190                                         break;
2191                                 }
2192                         } else {
2193                                 if (!is_track) {
2194                                         same_thing_soloed = true;
2195                                         break;
2196                                 }
2197                         }
2198                         break;
2199                 }
2200         }
2201         
2202         if (something_soloed != currently_soloing) {
2203                 signal = true;
2204                 currently_soloing = something_soloed;
2205         }
2206         
2207         modify_solo_mute (is_track, same_thing_soloed);
2208
2209         if (signal) {
2210                 SoloActive (currently_soloing); /* EMIT SIGNAL */
2211         }
2212
2213         SoloChanged (); /* EMIT SIGNAL */
2214
2215         set_dirty();
2216 }
2217
2218 void
2219 Session::update_route_solo_state ()
2220 {
2221         bool mute = false;
2222         bool is_track = false;
2223         bool signal = false;
2224
2225         /* caller must hold RouteLock */
2226
2227         /* this is where we actually implement solo by changing
2228            the solo mute setting of each track.
2229         */
2230         
2231         shared_ptr<RouteList> r = routes.reader ();
2232
2233         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2234                 if ((*i)->soloed()) {
2235                         mute = true;
2236                         if (dynamic_cast<AudioTrack*>((*i).get())) {
2237                                 is_track = true;
2238                         }
2239                         break;
2240                 }
2241         }
2242
2243         if (mute != currently_soloing) {
2244                 signal = true;
2245                 currently_soloing = mute;
2246         }
2247
2248         if (!is_track && !mute) {
2249
2250                 /* nothing is soloed */
2251
2252                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2253                         (*i)->set_solo_mute (false);
2254                 }
2255                 
2256                 if (signal) {
2257                         SoloActive (false);
2258                 }
2259
2260                 return;
2261         }
2262
2263         modify_solo_mute (is_track, mute);
2264
2265         if (signal) {
2266                 SoloActive (currently_soloing);
2267         }
2268 }
2269
2270 void
2271 Session::modify_solo_mute (bool is_track, bool mute)
2272 {
2273         shared_ptr<RouteList> r = routes.reader ();
2274
2275         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2276                 
2277                 if (is_track) {
2278                         
2279                         /* only alter track solo mute */
2280                         
2281                         if (dynamic_cast<AudioTrack*>((*i).get())) {
2282                                 if ((*i)->soloed()) {
2283                                         (*i)->set_solo_mute (!mute);
2284                                 } else {
2285                                         (*i)->set_solo_mute (mute);
2286                                 }
2287                         }
2288
2289                 } else {
2290
2291                         /* only alter bus solo mute */
2292
2293                         if (!dynamic_cast<AudioTrack*>((*i).get())) {
2294
2295                                 if ((*i)->soloed()) {
2296
2297                                         (*i)->set_solo_mute (false);
2298
2299                                 } else {
2300
2301                                         /* don't mute master or control outs
2302                                            in response to another bus solo
2303                                         */
2304                                         
2305                                         if ((*i) != _master_out &&
2306                                             (*i) != _control_out) {
2307                                                 (*i)->set_solo_mute (mute);
2308                                         }
2309                                 }
2310                         }
2311
2312                 }
2313         }
2314 }       
2315
2316
2317 void
2318 Session::catch_up_on_solo ()
2319 {
2320         /* this is called after set_state() to catch the full solo
2321            state, which can't be correctly determined on a per-route
2322            basis, but needs the global overview that only the session
2323            has.
2324         */
2325         update_route_solo_state();
2326 }       
2327                 
2328 shared_ptr<Route>
2329 Session::route_by_name (string name)
2330 {
2331         shared_ptr<RouteList> r = routes.reader ();
2332
2333         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2334                 if ((*i)->name() == name) {
2335                         return *i;
2336                 }
2337         }
2338
2339         return shared_ptr<Route> ((Route*) 0);
2340 }
2341
2342 shared_ptr<Route>
2343 Session::route_by_id (PBD::ID id)
2344 {
2345         shared_ptr<RouteList> r = routes.reader ();
2346
2347         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2348                 if ((*i)->id() == id) {
2349                         return *i;
2350                 }
2351         }
2352
2353         return shared_ptr<Route> ((Route*) 0);
2354 }
2355
2356 shared_ptr<Route>
2357 Session::route_by_remote_id (uint32_t id)
2358 {
2359         shared_ptr<RouteList> r = routes.reader ();
2360
2361         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2362                 if ((*i)->remote_control_id() == id) {
2363                         return *i;
2364                 }
2365         }
2366
2367         return shared_ptr<Route> ((Route*) 0);
2368 }
2369
2370 void
2371 Session::find_current_end ()
2372 {
2373         if (_state_of_the_state & Loading) {
2374                 return;
2375         }
2376
2377         nframes_t max = get_maximum_extent ();
2378
2379         if (max > end_location->end()) {
2380                 end_location->set_end (max);
2381                 set_dirty();
2382                 DurationChanged(); /* EMIT SIGNAL */
2383         }
2384 }
2385
2386 nframes_t
2387 Session::get_maximum_extent () const
2388 {
2389         nframes_t max = 0;
2390         nframes_t me; 
2391
2392         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2393
2394         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2395                 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2396                 if ((me = pl->get_maximum_extent()) > max) {
2397                         max = me;
2398                 }
2399         }
2400
2401         return max;
2402 }
2403
2404 boost::shared_ptr<Diskstream>
2405 Session::diskstream_by_name (string name)
2406 {
2407         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2408
2409         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2410                 if ((*i)->name() == name) {
2411                         return *i;
2412                 }
2413         }
2414
2415         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2416 }
2417
2418 boost::shared_ptr<Diskstream>
2419 Session::diskstream_by_id (const PBD::ID& id)
2420 {
2421         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2422
2423         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2424                 if ((*i)->id() == id) {
2425                         return *i;
2426                 }
2427         }
2428
2429         return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2430 }
2431
2432 /* AudioRegion management */
2433
2434 string
2435 Session::new_region_name (string old)
2436 {
2437         string::size_type last_period;
2438         uint32_t number;
2439         string::size_type len = old.length() + 64;
2440         char buf[len];
2441
2442         if ((last_period = old.find_last_of ('.')) == string::npos) {
2443                 
2444                 /* no period present - add one explicitly */
2445
2446                 old += '.';
2447                 last_period = old.length() - 1;
2448                 number = 0;
2449
2450         } else {
2451
2452                 number = atoi (old.substr (last_period+1).c_str());
2453
2454         }
2455
2456         while (number < (UINT_MAX-1)) {
2457
2458                 AudioRegionList::const_iterator i;
2459                 string sbuf;
2460
2461                 number++;
2462
2463                 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2464                 sbuf = buf;
2465
2466                 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2467                         if (i->second->name() == sbuf) {
2468                                 break;
2469                         }
2470                 }
2471                 
2472                 if (i == audio_regions.end()) {
2473                         break;
2474                 }
2475         }
2476
2477         if (number != (UINT_MAX-1)) {
2478                 return buf;
2479         } 
2480
2481         error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2482         return old;
2483 }
2484
2485 int
2486 Session::region_name (string& result, string base, bool newlevel) const
2487 {
2488         char buf[16];
2489         string subbase;
2490
2491         if (base == "") {
2492                 
2493                 Glib::Mutex::Lock lm (region_lock);
2494
2495                 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2496
2497                 
2498                 result = "region.";
2499                 result += buf;
2500
2501         } else {
2502
2503                 /* XXX this is going to be slow. optimize me later */
2504                 
2505                 if (newlevel) {
2506                         subbase = base;
2507                 } else {
2508                         string::size_type pos;
2509
2510                         pos = base.find_last_of ('.');
2511
2512                         /* pos may be npos, but then we just use entire base */
2513
2514                         subbase = base.substr (0, pos);
2515
2516                 }
2517
2518                 bool name_taken = true;
2519                 
2520                 {
2521                         Glib::Mutex::Lock lm (region_lock);
2522                         
2523                         for (int n = 1; n < 5000; ++n) {
2524                                 
2525                                 result = subbase;
2526                                 snprintf (buf, sizeof (buf), ".%d", n);
2527                                 result += buf;
2528                                 
2529                                 name_taken = false;
2530                                 
2531                                 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2532                                         if (i->second->name() == result) {
2533                                                 name_taken = true;
2534                                                 break;
2535                                         }
2536                                 }
2537                                 
2538                                 if (!name_taken) {
2539                                         break;
2540                                 }
2541                         }
2542                 }
2543                         
2544                 if (name_taken) {
2545                         fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2546                         /*NOTREACHED*/
2547                 }
2548         }
2549         return 0;
2550 }       
2551
2552 void
2553 Session::add_region (boost::shared_ptr<Region> region)
2554 {
2555         boost::shared_ptr<AudioRegion> ar;
2556         boost::shared_ptr<AudioRegion> oar;
2557         bool added = false;
2558
2559         { 
2560                 Glib::Mutex::Lock lm (region_lock);
2561
2562                 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2563
2564                         AudioRegionList::iterator x;
2565
2566                         for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2567
2568                                 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2569
2570                                 if (ar->region_list_equivalent (oar)) {
2571                                         break;
2572                                 }
2573                         }
2574
2575                         if (x == audio_regions.end()) {
2576
2577                                 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2578
2579                                 entry.first = region->id();
2580                                 entry.second = ar;
2581
2582                                 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2583
2584                                 
2585                                 if (!x.second) {
2586                                         return;
2587                                 }
2588
2589                                 added = true;
2590                         } 
2591
2592                 } else {
2593
2594                         fatal << _("programming error: ")
2595                               << X_("unknown region type passed to Session::add_region()")
2596                               << endmsg;
2597                         /*NOTREACHED*/
2598
2599                 }
2600         }
2601
2602         /* mark dirty because something has changed even if we didn't
2603            add the region to the region list.
2604         */
2605         
2606         set_dirty();
2607         
2608         if (added) {
2609                 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2610                 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2611                 AudioRegionAdded (ar); /* EMIT SIGNAL */
2612         }
2613 }
2614
2615 void
2616 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2617 {
2618         boost::shared_ptr<Region> region (weak_region.lock ());
2619
2620         if (!region) {
2621                 return;
2622         }
2623
2624         if (what_changed & Region::HiddenChanged) {
2625                 /* relay hidden changes */
2626                 RegionHiddenChange (region);
2627         }
2628 }
2629
2630 void
2631 Session::remove_region (boost::weak_ptr<Region> weak_region)
2632 {
2633         AudioRegionList::iterator i;
2634         boost::shared_ptr<Region> region (weak_region.lock ());
2635
2636         if (!region) {
2637                 return;
2638         }
2639
2640         boost::shared_ptr<AudioRegion> ar;
2641         bool removed = false;
2642
2643         { 
2644                 Glib::Mutex::Lock lm (region_lock);
2645
2646                 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2647                         if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2648                                 audio_regions.erase (i);
2649                                 removed = true;
2650                         }
2651
2652                 } else {
2653
2654                         fatal << _("programming error: ") 
2655                               << X_("unknown region type passed to Session::remove_region()")
2656                               << endmsg;
2657                         /*NOTREACHED*/
2658                 }
2659         }
2660
2661         /* mark dirty because something has changed even if we didn't
2662            remove the region from the region list.
2663         */
2664
2665         set_dirty();
2666
2667         if (removed) {
2668                 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2669         }
2670 }
2671
2672 boost::shared_ptr<AudioRegion>
2673 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2674 {
2675         AudioRegionList::iterator i;
2676         boost::shared_ptr<AudioRegion> region;
2677         Glib::Mutex::Lock lm (region_lock);
2678
2679         for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2680
2681                 region = i->second;
2682
2683                 if (region->whole_file()) {
2684
2685                         if (child->source_equivalent (region)) {
2686                                 return region;
2687                         }
2688                 }
2689         } 
2690
2691         return boost::shared_ptr<AudioRegion> ();
2692 }       
2693
2694 void
2695 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2696 {
2697         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2698                 (*i)->get_region_list_equivalent_regions (region, result);
2699 }
2700
2701 int
2702 Session::destroy_region (boost::shared_ptr<Region> region)
2703 {
2704         vector<boost::shared_ptr<Source> > srcs;
2705                 
2706         {
2707                 boost::shared_ptr<AudioRegion> aregion;
2708                 
2709                 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2710                         return 0;
2711                 }
2712                 
2713                 if (aregion->playlist()) {
2714                         aregion->playlist()->destroy_region (region);
2715                 }
2716                 
2717                 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2718                         srcs.push_back (aregion->source (n));
2719                 }
2720         }
2721
2722         region->drop_references ();
2723
2724         for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2725
2726                 if (!(*i)->used()) {
2727                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2728                         
2729                         if (afs) {
2730                                 (afs)->mark_for_remove ();
2731                         }
2732                         
2733                         (*i)->drop_references ();
2734                         
2735                         cerr << "source was not used by any playlist\n";
2736                 }
2737         }
2738
2739         return 0;
2740 }
2741
2742 int
2743 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2744 {
2745         for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2746                 destroy_region (*i);
2747         }
2748         return 0;
2749 }
2750
2751 int
2752 Session::remove_last_capture ()
2753 {
2754         list<boost::shared_ptr<Region> > r;
2755         
2756         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2757         
2758         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2759                 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2760                 
2761                 if (!l.empty()) {
2762                         r.insert (r.end(), l.begin(), l.end());
2763                         l.clear ();
2764                 }
2765         }
2766
2767         destroy_regions (r);
2768
2769         save_state (_current_snapshot_name);
2770
2771         return 0;
2772 }
2773
2774 int
2775 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2776 {
2777         remove_region (r);
2778         return 0;
2779 }
2780
2781 /* Source Management */
2782
2783 void
2784 Session::add_source (boost::shared_ptr<Source> source)
2785 {
2786         boost::shared_ptr<AudioFileSource> afs;
2787
2788         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2789
2790                 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2791                 pair<AudioSourceList::iterator,bool> result;
2792
2793                 entry.first = source->id();
2794                 entry.second = afs;
2795                 
2796                 {
2797                         Glib::Mutex::Lock lm (audio_source_lock);
2798                         result = audio_sources.insert (entry);
2799                 }
2800
2801                 if (result.second) {
2802                         source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2803                         set_dirty();
2804                 }
2805
2806         } 
2807 }
2808
2809 void
2810 Session::remove_source (boost::weak_ptr<Source> src)
2811 {
2812         AudioSourceList::iterator i;
2813         boost::shared_ptr<Source> source = src.lock();
2814
2815         if (!source) {
2816                 return;
2817         } 
2818
2819         { 
2820                 Glib::Mutex::Lock lm (audio_source_lock);
2821                 
2822                 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2823                         audio_sources.erase (i);
2824                 } 
2825         }
2826         
2827         if (!_state_of_the_state & InCleanup) {
2828                 
2829                 /* save state so we don't end up with a session file
2830                    referring to non-existent sources.
2831                 */
2832                 
2833                 save_state (_current_snapshot_name);
2834         }
2835 }
2836
2837 boost::shared_ptr<Source>
2838 Session::source_by_id (const PBD::ID& id)
2839 {
2840         Glib::Mutex::Lock lm (audio_source_lock);
2841         AudioSourceList::iterator i;
2842         boost::shared_ptr<Source> source;
2843
2844         if ((i = audio_sources.find (id)) != audio_sources.end()) {
2845                 source = i->second;
2846         }
2847
2848         /* XXX search MIDI or other searches here */
2849         
2850         return source;
2851 }
2852
2853
2854 boost::shared_ptr<Source>
2855 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2856 {
2857         Glib::Mutex::Lock lm (audio_source_lock);
2858
2859         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2860                 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2861
2862                 if (afs && afs->path() == path && chn == afs->channel()) {
2863                         return afs;
2864                 } 
2865                        
2866         }
2867         return boost::shared_ptr<Source>();
2868 }
2869
2870 string
2871 Session::peak_path_from_audio_path (string audio_path) const
2872 {
2873         string res;
2874
2875         res = peak_dir ();
2876         res += PBD::basename_nosuffix (audio_path);
2877         res += ".peak";
2878
2879         return res;
2880 }
2881
2882 string
2883 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2884 {
2885         string look_for;
2886         string old_basename = PBD::basename_nosuffix (oldname);
2887         string new_legalized = legalize_for_path (newname);
2888
2889         /* note: we know (or assume) the old path is already valid */
2890
2891         if (destructive) {
2892                 
2893                 /* destructive file sources have a name of the form:
2894
2895                     /path/to/Tnnnn-NAME(%[LR])?.wav
2896                   
2897                     the task here is to replace NAME with the new name.
2898                 */
2899                 
2900                 /* find last slash */
2901
2902                 string dir;
2903                 string prefix;
2904                 string::size_type slash;
2905                 string::size_type dash;
2906
2907                 if ((slash = path.find_last_of ('/')) == string::npos) {
2908                         return "";
2909                 }
2910
2911                 dir = path.substr (0, slash+1);
2912
2913                 /* '-' is not a legal character for the NAME part of the path */
2914
2915                 if ((dash = path.find_last_of ('-')) == string::npos) {
2916                         return "";
2917                 }
2918
2919                 prefix = path.substr (slash+1, dash-(slash+1));
2920
2921                 path = dir;
2922                 path += prefix;
2923                 path += '-';
2924                 path += new_legalized;
2925                 path += ".wav";  /* XXX gag me with a spoon */
2926                 
2927         } else {
2928                 
2929                 /* non-destructive file sources have a name of the form:
2930
2931                     /path/to/NAME-nnnnn(%[LR])?.wav
2932                   
2933                     the task here is to replace NAME with the new name.
2934                 */
2935                 
2936                 string dir;
2937                 string suffix;
2938                 string::size_type slash;
2939                 string::size_type dash;
2940                 string::size_type postfix;
2941
2942                 /* find last slash */
2943
2944                 if ((slash = path.find_last_of ('/')) == string::npos) {
2945                         return "";
2946                 }
2947
2948                 dir = path.substr (0, slash+1);
2949
2950                 /* '-' is not a legal character for the NAME part of the path */
2951
2952                 if ((dash = path.find_last_of ('-')) == string::npos) {
2953                         return "";
2954                 }
2955
2956                 suffix = path.substr (dash+1);
2957                 
2958                 // Suffix is now everything after the dash. Now we need to eliminate
2959                 // the nnnnn part, which is done by either finding a '%' or a '.'
2960
2961                 postfix = suffix.find_last_of ("%");
2962                 if (postfix == string::npos) {
2963                         postfix = suffix.find_last_of ('.');
2964                 }
2965
2966                 if (postfix != string::npos) {
2967                         suffix = suffix.substr (postfix);
2968                 } else {
2969                         error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2970                         return "";
2971                 }
2972
2973                 const uint32_t limit = 10000;
2974                 char buf[PATH_MAX+1];
2975
2976                 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2977
2978                         snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2979
2980                         if (access (buf, F_OK) != 0) {
2981                                 path = buf;
2982                                 break;
2983                         }
2984                         path = "";
2985                 }
2986
2987                 if (path == "") {
2988                         error << "FATAL ERROR! Could not find a " << endl;
2989                 }
2990
2991         }
2992
2993         return path;
2994 }
2995
2996 string
2997 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2998 {
2999         string spath;
3000         uint32_t cnt;
3001         char buf[PATH_MAX+1];
3002         const uint32_t limit = 10000;
3003         string legalized;
3004
3005         buf[0] = '\0';
3006         legalized = legalize_for_path (name);
3007
3008         /* find a "version" of the file name that doesn't exist in
3009            any of the possible directories.
3010         */
3011
3012         for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3013
3014                 vector<space_and_path>::iterator i;
3015                 uint32_t existing = 0;
3016
3017                 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3018
3019                         spath = (*i).path;
3020
3021                         spath += sound_dir (false);
3022
3023                         if (destructive) {
3024                                 if (nchan < 2) {
3025                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3026                                 } else if (nchan == 2) {
3027                                         if (chan == 0) {
3028                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3029                                         } else {
3030                                                 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3031                                         }
3032                                 } else if (nchan < 26) {
3033                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3034                                 } else {
3035                                         snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3036                                 }
3037
3038                         } else {
3039
3040                                 spath += '/';
3041                                 spath += legalized;
3042
3043                                 if (nchan < 2) {
3044                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3045                                 } else if (nchan == 2) {
3046                                         if (chan == 0) {
3047                                                 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3048                                         } else {
3049                                                 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3050                                         }
3051                                 } else if (nchan < 26) {
3052                                         snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3053                                 } else {
3054                                         snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3055                                 }
3056                         }
3057
3058                         if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3059                                 existing++;
3060                         } 
3061
3062                 }
3063
3064                 if (existing == 0) {
3065                         break;
3066                 }
3067
3068                 if (cnt > limit) {
3069                         error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3070                         destroy ();
3071                         throw failed_constructor();
3072                 }
3073         }
3074
3075         /* we now have a unique name for the file, but figure out where to
3076            actually put it.
3077         */
3078
3079         string foo = buf;
3080
3081         spath = discover_best_sound_dir ();
3082         spath += '/';
3083
3084         string::size_type pos = foo.find_last_of ('/');
3085         
3086         if (pos == string::npos) {
3087                 spath += foo;
3088         } else {
3089                 spath += foo.substr (pos + 1);
3090         }
3091
3092         return spath;
3093 }
3094
3095 boost::shared_ptr<AudioFileSource>
3096 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3097 {
3098         string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3099         return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3100 }
3101
3102 /* Playlist management */
3103
3104 boost::shared_ptr<Playlist>
3105 Session::playlist_by_name (string name)
3106 {
3107         Glib::Mutex::Lock lm (playlist_lock);
3108         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3109                 if ((*i)->name() == name) {
3110                         return* i;
3111                 }
3112         }
3113         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3114                 if ((*i)->name() == name) {
3115                         return* i;
3116                 }
3117         }
3118
3119         return boost::shared_ptr<Playlist>();
3120 }
3121
3122 void
3123 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3124 {
3125         if (playlist->hidden()) {
3126                 return;
3127         }
3128
3129         { 
3130                 Glib::Mutex::Lock lm (playlist_lock);
3131                 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3132                         playlists.insert (playlists.begin(), playlist);
3133                         playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3134                         playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3135                 }
3136         }
3137
3138         set_dirty();
3139
3140         PlaylistAdded (playlist); /* EMIT SIGNAL */
3141 }
3142
3143 void
3144 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3145 {
3146         { 
3147                 Glib::Mutex::Lock lm (playlist_lock);
3148                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3149                         s.push_back (*i);
3150                 }
3151                 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3152                         s.push_back (*i);
3153                 }
3154         }
3155 }
3156
3157 void
3158 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3159 {
3160         boost::shared_ptr<Playlist> pl(wpl.lock());
3161
3162         if (!pl) {
3163                 return;
3164         }
3165
3166         PlaylistList::iterator x;
3167
3168         if (pl->hidden()) {
3169                 /* its not supposed to be visible */
3170                 return;
3171         }
3172
3173         { 
3174                 Glib::Mutex::Lock lm (playlist_lock);
3175
3176                 if (!inuse) {
3177
3178                         unused_playlists.insert (pl);
3179                         
3180                         if ((x = playlists.find (pl)) != playlists.end()) {
3181                                 playlists.erase (x);
3182                         }
3183
3184                         
3185                 } else {
3186
3187                         playlists.insert (pl);
3188                         
3189                         if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3190                                 unused_playlists.erase (x);
3191                         }
3192                 }
3193         }
3194 }
3195
3196 void
3197 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3198 {
3199         if (_state_of_the_state & Deletion) {
3200                 return;
3201         }
3202
3203         boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3204
3205         if (!playlist) {
3206                 return;
3207         }
3208
3209         { 
3210                 Glib::Mutex::Lock lm (playlist_lock);
3211
3212                 PlaylistList::iterator i;
3213
3214                 i = find (playlists.begin(), playlists.end(), playlist);
3215                 if (i != playlists.end()) {
3216                         playlists.erase (i);
3217                 }
3218
3219                 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3220                 if (i != unused_playlists.end()) {
3221                         unused_playlists.erase (i);
3222                 }
3223                 
3224         }
3225
3226         set_dirty();
3227
3228         PlaylistRemoved (playlist); /* EMIT SIGNAL */
3229 }
3230
3231 void 
3232 Session::set_audition (boost::shared_ptr<Region> r)
3233 {
3234         pending_audition_region = r;
3235         post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3236         schedule_butler_transport_work ();
3237 }
3238
3239 void
3240 Session::audition_playlist ()
3241 {
3242         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3243         ev->region.reset ();
3244         queue_event (ev);
3245 }
3246
3247 void
3248 Session::non_realtime_set_audition ()
3249 {
3250         if (!pending_audition_region) {
3251                 auditioner->audition_current_playlist ();
3252         } else {
3253                 auditioner->audition_region (pending_audition_region);
3254                 pending_audition_region.reset ();
3255         }
3256         AuditionActive (true); /* EMIT SIGNAL */
3257 }
3258
3259 void
3260 Session::audition_region (boost::shared_ptr<Region> r)
3261 {
3262         Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3263         ev->region = r;
3264         queue_event (ev);
3265 }
3266
3267 void
3268 Session::cancel_audition ()
3269 {
3270         if (auditioner->active()) {
3271                 auditioner->cancel_audition ();
3272                 AuditionActive (false); /* EMIT SIGNAL */
3273         }
3274 }
3275
3276 bool
3277 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3278 {
3279         return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3280 }
3281
3282 void
3283 Session::remove_empty_sounds ()
3284 {
3285         PathScanner scanner;
3286
3287         vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3288         
3289         Glib::Mutex::Lock lm (audio_source_lock);
3290         
3291         regex_t compiled_tape_track_pattern;
3292         int err;
3293
3294         if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3295
3296                 char msg[256];
3297                 
3298                 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3299                 
3300                 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3301                 return;
3302         }
3303
3304         for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3305                 
3306                 /* never remove files that appear to be a tape track */
3307
3308                 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3309                         delete *i;
3310                         continue;
3311                 }
3312                         
3313                 if (AudioFileSource::is_empty (*this, *(*i))) {
3314
3315                         unlink ((*i)->c_str());
3316                         
3317                         string peak_path = peak_path_from_audio_path (**i);
3318                         unlink (peak_path.c_str());
3319                 }
3320
3321                 delete* i;
3322         }
3323
3324         delete possible_audiofiles;
3325 }
3326
3327 bool
3328 Session::is_auditioning () const
3329 {
3330         /* can be called before we have an auditioner object */
3331         if (auditioner) {
3332                 return auditioner->active();
3333         } else {
3334                 return false;
3335         }
3336 }
3337
3338 void
3339 Session::set_all_solo (bool yn)
3340 {
3341         shared_ptr<RouteList> r = routes.reader ();
3342         
3343         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3344                 if (!(*i)->hidden()) {
3345                         (*i)->set_solo (yn, this);
3346                 }
3347         }
3348
3349         set_dirty();
3350 }
3351                 
3352 void
3353 Session::set_all_mute (bool yn)
3354 {
3355         shared_ptr<RouteList> r = routes.reader ();
3356         
3357         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3358                 if (!(*i)->hidden()) {
3359                         (*i)->set_mute (yn, this);
3360                 }
3361         }
3362
3363         set_dirty();
3364 }
3365                 
3366 uint32_t
3367 Session::n_diskstreams () const
3368 {
3369         uint32_t n = 0;
3370
3371         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3372
3373         for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3374                 if (!(*i)->hidden()) {
3375                         n++;
3376                 }
3377         }
3378         return n;
3379 }
3380
3381 void
3382 Session::graph_reordered ()
3383 {
3384         /* don't do this stuff if we are setting up connections
3385            from a set_state() call or creating new tracks.
3386         */
3387
3388         if (_state_of_the_state & InitialConnecting) {
3389                 return;
3390         }
3391
3392         /* every track/bus asked for this to be handled but it was deferred because
3393            we were connecting. do it now.
3394         */
3395
3396         request_input_change_handling ();
3397
3398         resort_routes ();
3399
3400         /* force all diskstreams to update their capture offset values to 
3401            reflect any changes in latencies within the graph.
3402         */
3403         
3404         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3405
3406         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3407                 (*i)->set_capture_offset ();
3408         }
3409 }
3410
3411 void
3412 Session::record_disenable_all ()
3413 {
3414         record_enable_change_all (false);
3415 }
3416
3417 void
3418 Session::record_enable_all ()
3419 {
3420         record_enable_change_all (true);
3421 }
3422
3423 void
3424 Session::record_enable_change_all (bool yn)
3425 {
3426         shared_ptr<RouteList> r = routes.reader ();
3427         
3428         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3429                 AudioTrack* at;
3430
3431                 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3432                         at->set_record_enable (yn, this);
3433                 }
3434         }
3435         
3436         /* since we don't keep rec-enable state, don't mark session dirty */
3437 }
3438
3439 void
3440 Session::add_redirect (Redirect* redirect)
3441 {
3442         Send* send;
3443         Insert* insert;
3444         PortInsert* port_insert;
3445         PluginInsert* plugin_insert;
3446
3447         if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3448                 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3449                         _port_inserts.insert (_port_inserts.begin(), port_insert);
3450                 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3451                         _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3452                 } else {
3453                         fatal << _("programming error: unknown type of Insert created!") << endmsg;
3454                         /*NOTREACHED*/
3455                 }
3456         } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3457                 _sends.insert (_sends.begin(), send);
3458         } else {
3459                 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3460                 /*NOTREACHED*/
3461         }
3462
3463         redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3464
3465         set_dirty();
3466 }
3467
3468 void
3469 Session::remove_redirect (Redirect* redirect)
3470 {
3471         Send* send;
3472         Insert* insert;
3473         PortInsert* port_insert;
3474         PluginInsert* plugin_insert;
3475         
3476         if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3477                 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3478                         list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3479                         if (x != _port_inserts.end()) {
3480                                 insert_bitset[port_insert->bit_slot()] = false;
3481                                 _port_inserts.erase (x);
3482                         }
3483                 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3484                         _plugin_inserts.remove (plugin_insert);
3485                 } else {
3486                         fatal << string_compose (_("programming error: %1"),
3487                                                  X_("unknown type of Insert deleted!")) 
3488                               << endmsg;
3489                         /*NOTREACHED*/
3490                 }
3491         } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3492                 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3493                 if (x != _sends.end()) {
3494                         send_bitset[send->bit_slot()] = false;
3495                         _sends.erase (x);
3496                 }
3497         } else {
3498                 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3499                 /*NOTREACHED*/
3500         }
3501
3502         set_dirty();
3503 }
3504
3505 nframes_t
3506 Session::available_capture_duration ()
3507 {
3508         float sample_bytes_on_disk = 4.0; // keep gcc happy
3509
3510         switch (Config->get_native_file_data_format()) {
3511         case FormatFloat:
3512                 sample_bytes_on_disk = 4.0;
3513                 break;
3514
3515         case FormatInt24:
3516                 sample_bytes_on_disk = 3.0;
3517                 break;
3518
3519         default: 
3520                 /* impossible, but keep some gcc versions happy */
3521                 fatal << string_compose (_("programming error: %1"),
3522                                          X_("illegal native file data format"))
3523                       << endmsg;
3524                 /*NOTREACHED*/
3525         }
3526
3527         double scale = 4096.0 / sample_bytes_on_disk;
3528
3529         if (_total_free_4k_blocks * scale > (double) max_frames) {
3530                 return max_frames;
3531         }
3532         
3533         return (nframes_t) floor (_total_free_4k_blocks * scale);
3534 }
3535
3536 void
3537 Session::add_connection (ARDOUR::Connection* connection)
3538 {
3539         {
3540                 Glib::Mutex::Lock guard (connection_lock);
3541                 _connections.push_back (connection);
3542         }
3543         
3544         ConnectionAdded (connection); /* EMIT SIGNAL */
3545
3546         set_dirty();
3547 }
3548
3549 void
3550 Session::remove_connection (ARDOUR::Connection* connection)
3551 {
3552         bool removed = false;
3553
3554         {
3555                 Glib::Mutex::Lock guard (connection_lock);
3556                 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3557                 
3558                 if (i != _connections.end()) {
3559                         _connections.erase (i);
3560                         removed = true;
3561                 }
3562         }
3563
3564         if (removed) {
3565                  ConnectionRemoved (connection); /* EMIT SIGNAL */
3566         }
3567
3568         set_dirty();
3569 }
3570
3571 ARDOUR::Connection *
3572 Session::connection_by_name (string name) const
3573 {
3574         Glib::Mutex::Lock lm (connection_lock);
3575
3576         for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3577                 if ((*i)->name() == name) {
3578                         return* i;
3579                 }
3580         }
3581
3582         return 0;
3583 }
3584
3585 void
3586 Session::tempo_map_changed (Change ignored)
3587 {
3588         clear_clicks ();
3589         set_dirty ();
3590 }
3591
3592 void
3593 Session::ensure_passthru_buffers (uint32_t howmany)
3594 {
3595         while (howmany > _passthru_buffers.size()) {
3596                 Sample *p;
3597 #ifdef NO_POSIX_MEMALIGN
3598                 p =  (Sample *) malloc(current_block_size * sizeof(Sample));
3599 #else
3600                 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3601 #endif                  
3602                 _passthru_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 * 4);
3610 #endif                  
3611                 memset (p, 0, sizeof (Sample) * current_block_size);
3612                 _silent_buffers.push_back (p);
3613
3614                 *p = 0;
3615                 
3616 #ifdef NO_POSIX_MEMALIGN
3617                 p =  (Sample *) malloc(current_block_size * sizeof(Sample));
3618 #else
3619                 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3620 #endif                  
3621                 memset (p, 0, sizeof (Sample) * current_block_size);
3622                 _send_buffers.push_back (p);
3623                 
3624         }
3625         allocate_pan_automation_buffers (current_block_size, howmany, false);
3626 }
3627
3628 uint32_t
3629 Session::next_insert_id ()
3630 {
3631         /* this doesn't really loop forever. just think about it */
3632
3633         while (true) {
3634                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3635                         if (!insert_bitset[n]) {
3636                                 insert_bitset[n] = true;
3637                                 return n;
3638                                 
3639                         }
3640                 }
3641                 
3642                 /* none available, so resize and try again */
3643
3644                 insert_bitset.resize (insert_bitset.size() + 16, false);
3645         }
3646 }
3647
3648 uint32_t
3649 Session::next_send_id ()
3650 {
3651         /* this doesn't really loop forever. just think about it */
3652
3653         while (true) {
3654                 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3655                         if (!send_bitset[n]) {
3656                                 send_bitset[n] = true;
3657                                 return n;
3658                                 
3659                         }
3660                 }
3661                 
3662                 /* none available, so resize and try again */
3663
3664                 send_bitset.resize (send_bitset.size() + 16, false);
3665         }
3666 }
3667
3668 void
3669 Session::mark_send_id (uint32_t id)
3670 {
3671         if (id >= send_bitset.size()) {
3672                 send_bitset.resize (id+16, false);
3673         }
3674         if (send_bitset[id]) {
3675                 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3676         }
3677         send_bitset[id] = true;
3678 }
3679
3680 void
3681 Session::mark_insert_id (uint32_t id)
3682 {
3683         if (id >= insert_bitset.size()) {
3684                 insert_bitset.resize (id+16, false);
3685         }
3686         if (insert_bitset[id]) {
3687                 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3688         }
3689         insert_bitset[id] = true;
3690 }
3691
3692 /* Named Selection management */
3693
3694 NamedSelection *
3695 Session::named_selection_by_name (string name)
3696 {
3697         Glib::Mutex::Lock lm (named_selection_lock);
3698         for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3699                 if ((*i)->name == name) {
3700                         return* i;
3701                 }
3702         }
3703         return 0;
3704 }
3705
3706 void
3707 Session::add_named_selection (NamedSelection* named_selection)
3708 {
3709         { 
3710                 Glib::Mutex::Lock lm (named_selection_lock);
3711                 named_selections.insert (named_selections.begin(), named_selection);
3712         }
3713
3714         for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3715                 add_playlist (*i);
3716         }
3717
3718         set_dirty();
3719
3720         NamedSelectionAdded (); /* EMIT SIGNAL */
3721 }
3722
3723 void
3724 Session::remove_named_selection (NamedSelection* named_selection)
3725 {
3726         bool removed = false;
3727
3728         { 
3729                 Glib::Mutex::Lock lm (named_selection_lock);
3730
3731                 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3732
3733                 if (i != named_selections.end()) {
3734                         delete (*i);
3735                         named_selections.erase (i);
3736                         set_dirty();
3737                         removed = true;
3738                 }
3739         }
3740
3741         if (removed) {
3742                  NamedSelectionRemoved (); /* EMIT SIGNAL */
3743         }
3744 }
3745
3746 void
3747 Session::reset_native_file_format ()
3748 {
3749         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3750
3751         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3752                 (*i)->reset_write_sources (false);
3753         }
3754 }
3755
3756 bool
3757 Session::route_name_unique (string n) const
3758 {
3759         shared_ptr<RouteList> r = routes.reader ();
3760         
3761         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3762                 if ((*i)->name() == n) {
3763                         return false;
3764                 }
3765         }
3766         
3767         return true;
3768 }
3769
3770 uint32_t
3771 Session::n_playlists () const
3772 {
3773         Glib::Mutex::Lock lm (playlist_lock);
3774         return playlists.size();
3775 }
3776
3777 void
3778 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3779 {
3780         if (!force && howmany <= _npan_buffers) {
3781                 return;
3782         }
3783
3784         if (_pan_automation_buffer) {
3785
3786                 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3787                         delete [] _pan_automation_buffer[i];
3788                 }
3789
3790                 delete [] _pan_automation_buffer;
3791         }
3792
3793         _pan_automation_buffer = new pan_t*[howmany];
3794         
3795         for (uint32_t i = 0; i < howmany; ++i) {
3796                 _pan_automation_buffer[i] = new pan_t[nframes];
3797         }
3798
3799         _npan_buffers = howmany;
3800 }
3801
3802 int
3803 Session::freeze (InterThreadInfo& itt)
3804 {
3805         shared_ptr<RouteList> r = routes.reader ();
3806
3807         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3808
3809                 AudioTrack *at;
3810
3811                 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3812                         /* XXX this is wrong because itt.progress will keep returning to zero at the start
3813                            of every track.
3814                         */
3815                         at->freeze (itt);
3816                 }
3817         }
3818
3819         return 0;
3820 }
3821
3822 int
3823 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,      
3824                                bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3825 {
3826         int ret = -1;
3827         boost::shared_ptr<Playlist> playlist;
3828         boost::shared_ptr<AudioFileSource> fsource;
3829         uint32_t x;
3830         char buf[PATH_MAX+1];
3831         string dir;
3832         uint32_t nchans;
3833         nframes_t position;
3834         nframes_t this_chunk;
3835         nframes_t to_do;
3836         vector<Sample*> buffers;
3837
3838         // any bigger than this seems to cause stack overflows in called functions
3839         const nframes_t chunk_size = (128 * 1024)/4;
3840
3841         g_atomic_int_set (&processing_prohibited, 1);
3842         
3843         /* call tree *MUST* hold route_lock */
3844         
3845         if ((playlist = track.diskstream()->playlist()) == 0) {
3846                 goto out;
3847         }
3848
3849         /* external redirects will be a problem */
3850
3851         if (track.has_external_redirects()) {
3852                 goto out;
3853         }
3854
3855         nchans = track.audio_diskstream()->n_channels();
3856         
3857         dir = discover_best_sound_dir ();
3858
3859         for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3860
3861                 for (x = 0; x < 99999; ++x) {
3862                         snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3863                         if (access (buf, F_OK) != 0) {
3864                                 break;
3865                         }
3866                 }
3867                 
3868                 if (x == 99999) {
3869                         error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3870                         goto out;
3871                 }
3872                 
3873                 try {
3874                         fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3875                 }
3876                 
3877                 catch (failed_constructor& err) {
3878                         error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3879                         goto out;
3880                 }
3881
3882                 srcs.push_back (fsource);
3883         }
3884
3885         /* XXX need to flush all redirects */
3886         
3887         position = start;
3888         to_do = len;
3889
3890         /* create a set of reasonably-sized buffers */
3891
3892         for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3893                 Sample* b;
3894 #ifdef NO_POSIX_MEMALIGN
3895                 b =  (Sample *) malloc(chunk_size * sizeof(Sample));
3896 #else
3897                 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
3898 #endif                  
3899                 buffers.push_back (b);
3900         }
3901
3902         for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3903                 (*src)->prepare_for_peakfile_writes ();
3904         }
3905                         
3906         while (to_do && !itt.cancel) {
3907                 
3908                 this_chunk = min (to_do, chunk_size);
3909                 
3910                 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3911                         goto out;
3912                 }
3913
3914                 uint32_t n = 0;
3915                 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3916                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3917                         
3918                         if (afs) {
3919                                 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3920                                         goto out;
3921                                 }
3922                         }
3923                 }
3924                 
3925                 start += this_chunk;
3926                 to_do -= this_chunk;
3927                 
3928                 itt.progress = (float) (1.0 - ((double) to_do / len));
3929
3930         }
3931
3932         if (!itt.cancel) {
3933                 
3934                 time_t now;
3935                 struct tm* xnow;
3936                 time (&now);
3937                 xnow = localtime (&now);
3938                 
3939                 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3940                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3941
3942                         if (afs) {
3943                                 afs->update_header (position, *xnow, now);
3944                                 afs->flush_header ();
3945                         }
3946                 }
3947                 
3948                 /* construct a region to represent the bounced material */
3949
3950                 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(), 
3951                                                                            region_name_from_path (srcs.front()->name(), true));
3952
3953                 ret = 0;
3954         }
3955                 
3956   out:
3957         if (ret) {
3958                 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3959                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3960
3961                         if (afs) {
3962                                 afs->mark_for_remove ();
3963                         }
3964
3965                         (*src)->drop_references ();
3966                 }
3967
3968         } else {
3969                 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3970                         (*src)->done_with_peakfile_writes ();
3971                 }
3972         }
3973
3974         for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3975                 free(*i);
3976         }
3977
3978         g_atomic_int_set (&processing_prohibited, 0);
3979
3980         itt.done = true;
3981
3982         return ret;
3983 }
3984
3985 vector<Sample*>&
3986 Session::get_silent_buffers (uint32_t howmany)
3987 {
3988         for (uint32_t i = 0; i < howmany; ++i) {
3989                 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3990         }
3991         return _silent_buffers;
3992 }
3993
3994 uint32_t 
3995 Session::ntracks () const
3996 {
3997         uint32_t n = 0;
3998         shared_ptr<RouteList> r = routes.reader ();
3999
4000         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4001                 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4002                         ++n;
4003                 }
4004         }
4005
4006         return n;
4007 }
4008
4009 uint32_t 
4010 Session::nbusses () const
4011 {
4012         uint32_t n = 0;
4013         shared_ptr<RouteList> r = routes.reader ();
4014
4015         for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4016                 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4017                         ++n;
4018                 }
4019         }
4020
4021         return n;
4022 }
4023
4024 void
4025 Session::add_automation_list(AutomationList *al)
4026 {
4027         automation_lists[al->id()] = al;
4028 }
4029
4030 nframes_t
4031 Session::compute_initial_length ()
4032 {
4033         return _engine.frame_rate() * 60 * 5;
4034 }
4035