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