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