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