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