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