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