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