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