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