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