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