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