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