2336baac75965f7443287adef6fd0a7271084f72
[ardour.git] / libs / ardour / midi_track.cc
1 /*
2     Copyright (C) 2006 Paul Davis 
3         By Dave Robillard, 2006
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <pbd/error.h>
20 #include <sigc++/retype.h>
21 #include <sigc++/retype_return.h>
22 #include <sigc++/bind.h>
23
24 #include <ardour/midi_track.h>
25 #include <ardour/midi_diskstream.h>
26 #include <ardour/session.h>
27 #include <ardour/redirect.h>
28 #include <ardour/midi_region.h>
29 #include <ardour/midi_source.h>
30 #include <ardour/route_group_specialized.h>
31 #include <ardour/insert.h>
32 #include <ardour/midi_playlist.h>
33 #include <ardour/panner.h>
34 #include <ardour/utils.h>
35 #include <ardour/buffer_set.h>
36
37 #include "i18n.h"
38
39 using namespace std;
40 using namespace ARDOUR;
41 using namespace PBD;
42
43 MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
44         : Track (sess, name, flag, mode, DataType::MIDI)
45 {
46         MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
47
48         if (_flags & Hidden) {
49                 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
50         } else {
51                 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
52         }
53
54         assert(mode != Destructive);
55
56         boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, name, dflags));
57         _session.add_diskstream (ds);
58
59         set_diskstream (boost::dynamic_pointer_cast<MidiDiskstream> (ds));
60         
61         _declickable = true;
62         _freeze_record.state = NoFreeze;
63         _saved_meter_point = _meter_point;
64         _mode = mode;
65
66         set_input_minimum(ChanCount(DataType::MIDI, 1));
67         set_input_maximum(ChanCount(DataType::MIDI, 1));
68         set_output_minimum(ChanCount(DataType::MIDI, 1));
69         set_output_maximum(ChanCount(DataType::MIDI, 1));
70 }
71
72 MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
73         : Track (sess, node)
74 {
75         _freeze_record.state = NoFreeze;
76         set_state (node);
77         _declickable = true;
78         _saved_meter_point = _meter_point;
79         
80         set_input_minimum(ChanCount(DataType::MIDI, 1));
81         set_input_maximum(ChanCount(DataType::MIDI, 1));
82         set_output_minimum(ChanCount(DataType::MIDI, 1));
83         set_output_maximum(ChanCount(DataType::MIDI, 1));
84 }
85
86 MidiTrack::~MidiTrack ()
87 {
88 }
89
90
91 int
92 MidiTrack::set_diskstream (boost::shared_ptr<MidiDiskstream> ds)
93 {
94         _diskstream = ds;
95         _diskstream->set_io (*this);
96         _diskstream->set_destructive (_mode == Destructive);
97
98         _diskstream->set_record_enabled (false);
99         //_diskstream->monitor_input (false);
100
101         ic_connection.disconnect();
102         ic_connection = input_changed.connect (mem_fun (*_diskstream, &MidiDiskstream::handle_input_change));
103
104         DiskstreamChanged (); /* EMIT SIGNAL */
105
106         return 0;
107 }       
108
109 int 
110 MidiTrack::use_diskstream (string name)
111 {
112         boost::shared_ptr<MidiDiskstream> dstream;
113
114         if ((dstream = boost::dynamic_pointer_cast<MidiDiskstream>(_session.diskstream_by_name (name))) == 0) {
115                 error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), name) << endmsg;
116                 return -1;
117         }
118         
119         return set_diskstream (dstream);
120 }
121
122 int 
123 MidiTrack::use_diskstream (const PBD::ID& id)
124 {
125         boost::shared_ptr<MidiDiskstream> dstream;
126
127         if ((dstream = boost::dynamic_pointer_cast<MidiDiskstream> (_session.diskstream_by_id (id))) == 0) {
128                 error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), id) << endmsg;
129                 return -1;
130         }
131         
132         return set_diskstream (dstream);
133 }
134
135 boost::shared_ptr<MidiDiskstream>
136 MidiTrack::midi_diskstream() const
137 {
138         return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
139 }
140
141 int
142 MidiTrack::set_state (const XMLNode& node)
143 {
144         const XMLProperty *prop;
145         XMLNodeConstIterator iter;
146
147         if (Route::set_state (node)) {
148                 return -1;
149         }
150
151         if ((prop = node.property (X_("mode"))) != 0) {
152                 if (prop->value() == X_("normal")) {
153                         _mode = Normal;
154                 } else if (prop->value() == X_("destructive")) {
155                         _mode = Destructive;
156                 } else {
157                         warning << string_compose ("unknown midi track mode \"%1\" seen and ignored", prop->value()) << endmsg;
158                         _mode = Normal;
159                 }
160         } else {
161                 _mode = Normal;
162         }
163
164         if ((prop = node.property ("diskstream-id")) == 0) {
165                 
166                 /* some old sessions use the diskstream name rather than the ID */
167
168                 if ((prop = node.property ("diskstream")) == 0) {
169                         fatal << _("programming error: MidiTrack given state without diskstream!") << endmsg;
170                         /*NOTREACHED*/
171                         return -1;
172                 }
173
174                 if (use_diskstream (prop->value())) {
175                         return -1;
176                 }
177
178         } else {
179                 
180                 PBD::ID id (prop->value());
181                 
182                 if (use_diskstream (id)) {
183                         return -1;
184                 }
185         }
186
187
188         XMLNodeList nlist;
189         XMLNodeConstIterator niter;
190         XMLNode *child;
191
192         nlist = node.children();
193         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
194                 child = *niter;
195
196                 if (child->name() == X_("remote_control")) {
197                         if ((prop = child->property (X_("id"))) != 0) {
198                                 int32_t x;
199                                 sscanf (prop->value().c_str(), "%d", &x);
200                                 set_remote_control_id (x);
201                         }
202                 }
203         }
204
205         pending_state = const_cast<XMLNode*> (&node);
206
207         _session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two));
208
209         return 0;
210 }
211
212 XMLNode& 
213 MidiTrack::state(bool full_state)
214 {
215         XMLNode& root (Route::state(full_state));
216         XMLNode* freeze_node;
217         char buf[64];
218
219         if (_freeze_record.playlist) {
220                 XMLNode* inode;
221
222                 freeze_node = new XMLNode (X_("freeze-info"));
223                 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
224                 snprintf (buf, sizeof (buf), "%d", (int) _freeze_record.state);
225                 freeze_node->add_property ("state", buf);
226
227                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
228                         inode = new XMLNode (X_("insert"));
229                         (*i)->id.print (buf);
230                         inode->add_property (X_("id"), buf);
231                         inode->add_child_copy ((*i)->state);
232                 
233                         freeze_node->add_child_nocopy (*inode);
234                 }
235
236                 root.add_child_nocopy (*freeze_node);
237         }
238
239         /* Alignment: act as a proxy for the diskstream */
240         
241         XMLNode* align_node = new XMLNode (X_("alignment"));
242         switch (_diskstream->alignment_style()) {
243         case ExistingMaterial:
244                 snprintf (buf, sizeof (buf), X_("existing"));
245                 break;
246         case CaptureTime:
247                 snprintf (buf, sizeof (buf), X_("capture"));
248                 break;
249         }
250         align_node->add_property (X_("style"), buf);
251         root.add_child_nocopy (*align_node);
252
253         XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
254         snprintf (buf, sizeof (buf), "%d", _remote_control_id);
255         remote_control_node->add_property (X_("id"), buf);
256         root.add_child_nocopy (*remote_control_node);
257
258         switch (_mode) {
259         case Normal:
260                 root.add_property (X_("mode"), X_("normal"));
261                 break;
262         case Destructive:
263                 root.add_property (X_("mode"), X_("destructive"));
264                 break;
265         }
266
267         /* we don't return diskstream state because we don't
268            own the diskstream exclusively. control of the diskstream
269            state is ceded to the Session, even if we create the
270            diskstream.
271         */
272
273         _diskstream->id().print (buf);
274         root.add_property ("diskstream-id", buf);
275
276         return root;
277 }
278
279 void
280 MidiTrack::set_state_part_two ()
281 {
282         XMLNode* fnode;
283         XMLProperty* prop;
284         LocaleGuard lg (X_("POSIX"));
285
286         /* This is called after all session state has been restored but before
287            have been made ports and connections are established.
288         */
289
290         if (pending_state == 0) {
291                 return;
292         }
293
294         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
295
296                 
297                 _freeze_record.have_mementos = false;
298                 _freeze_record.state = Frozen;
299                 
300                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
301                         delete *i;
302                 }
303                 _freeze_record.insert_info.clear ();
304                 
305                 if ((prop = fnode->property (X_("playlist"))) != 0) {
306                         Playlist* pl = _session.playlist_by_name (prop->value());
307                         if (pl) {
308                                 _freeze_record.playlist = dynamic_cast<MidiPlaylist*> (pl);
309                         } else {
310                                 _freeze_record.playlist = 0;
311                                 _freeze_record.state = NoFreeze;
312                         return;
313                         }
314                 }
315                 
316                 if ((prop = fnode->property (X_("state"))) != 0) {
317                         _freeze_record.state = (FreezeState) atoi (prop->value().c_str());
318                 }
319                 
320                 XMLNodeConstIterator citer;
321                 XMLNodeList clist = fnode->children();
322                 
323                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
324                         if ((*citer)->name() != X_("insert")) {
325                                 continue;
326                         }
327                         
328                         if ((prop = (*citer)->property (X_("id"))) == 0) {
329                                 continue;
330                         }
331                         
332                         FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()),
333                                                                                    boost::shared_ptr<Insert>());
334                         frii->id = prop->value ();
335                         _freeze_record.insert_info.push_back (frii);
336                 }
337         }
338
339         /* Alignment: act as a proxy for the diskstream */
340
341         if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
342
343                 if ((prop = fnode->property (X_("style"))) != 0) {
344                         if (prop->value() == "existing") {
345                                 _diskstream->set_persistent_align_style (ExistingMaterial);
346                         } else if (prop->value() == "capture") {
347                                 _diskstream->set_persistent_align_style (CaptureTime);
348                         }
349                 }
350         }
351         return;
352 }       
353
354 int 
355 MidiTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, 
356                      bool session_state_changing, bool can_record, bool rec_monitors_input)
357 {
358         if (n_outputs().get(DataType::MIDI) == 0) {
359                 //return 0;
360                 throw; // FIXME
361         }
362
363         if (!_active) {
364                 silence (nframes, offset);
365                 //return 0; // FIXME
366         }
367
368         if (session_state_changing) {
369
370                 /* XXX is this safe to do against transport state changes? */
371
372                 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
373                 return 0;
374         }
375
376         midi_diskstream()->check_record_status (start_frame, nframes, can_record);
377
378         bool send_silence;
379         
380         if (_have_internal_generator) {
381                 /* since the instrument has no input streams,
382                    there is no reason to send any signal
383                    into the route.
384                 */
385                 send_silence = true;
386         } else {
387
388                 if (_session.get_auto_input()) {
389                         if (Config->get_use_sw_monitoring()) {
390                                 send_silence = false;
391                         } else {
392                                 send_silence = true;
393                         }
394                 } else {
395                         if (_diskstream->record_enabled()) {
396                                 if (Config->get_use_sw_monitoring()) {
397                                         send_silence = false;
398                                 } else {
399                                         send_silence = true;
400                                 }
401                         } else {
402                                 send_silence = true;
403                         }
404                 }
405         }
406
407         apply_gain_automation = false;
408
409         if (send_silence) {
410                 
411                 /* if we're sending silence, but we want the meters to show levels for the signal,
412                    meter right here.
413                 */
414                 
415                 if (_have_internal_generator) {
416                         passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
417                 } else {
418                         if (_meter_point == MeterInput) {
419                                 just_meter_input (start_frame, end_frame, nframes, offset);
420                         }
421                         passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
422                 }
423
424         } else {
425         
426                 /* we're sending signal, but we may still want to meter the input. 
427                  */
428
429                 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
430         }
431
432         return 0;
433 }
434
435 int
436 MidiTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
437                   bool can_record, bool rec_monitors_input)
438 {
439         int dret;
440         boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
441
442         {
443                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
444                 if (lm.locked()) {
445                         // automation snapshot can also be called from the non-rt context
446                         // and it uses the redirect list, so we take the lock out here
447                         automation_snapshot (start_frame);
448                 }
449         }
450
451         if (n_outputs().get_total() == 0 && _redirects.empty()) {
452                 return 0;
453         }
454
455         if (!_active) {
456                 silence (nframes, offset);
457                 return 0;
458         }
459
460         jack_nframes_t transport_frame = _session.transport_frame();
461
462         if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
463                 /* need to do this so that the diskstream sets its
464                    playback distance to zero, thus causing diskstream::commit
465                    to do nothing.
466                    */
467                 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
468         } 
469
470         _silent = false;
471
472         if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
473
474                 silence (nframes, offset);
475
476                 return dret;
477         }
478
479         /* special condition applies */
480
481         if (_meter_point == MeterInput) {
482                 just_meter_input (start_frame, end_frame, nframes, offset);
483         }
484
485         if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
486
487                 /* not actually recording, but we want to hear the input material anyway,
488                    at least potentially (depending on monitoring options)
489                    */
490
491                 passthru (start_frame, end_frame, nframes, offset, 0, true);
492
493         } else {
494                 /*
495                    XXX is it true that the earlier test on n_outputs()
496                    means that we can avoid checking it again here? i think
497                    so, because changing the i/o configuration of an IO
498                    requires holding the AudioEngine lock, which we hold
499                    while in the process() tree.
500                    */
501
502
503                 /* copy the diskstream data to all output buffers */
504
505                 //const size_t limit = n_process_buffers().get(DataType::AUDIO);
506                 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
507
508                 diskstream->get_playback(bufs.get_midi(0), start_frame, end_frame);
509
510                 process_output_buffers (bufs, start_frame, end_frame, nframes, offset,
511                                 (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
512         
513         }
514
515         return 0;
516 }
517
518 int
519 MidiTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, 
520                          bool can_record, bool rec_monitors_input)
521 {
522         if (n_outputs().get(DataType::MIDI) == 0 && _redirects.empty()) {
523                 return 0;
524         }
525
526         if (!_active) {
527                 silence (nframes, offset);
528                 return 0;
529         }
530
531         _silent = true;
532         apply_gain_automation = false;
533
534         silence (nframes, offset);
535
536         return midi_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
537 }
538
539 void
540 MidiTrack::process_output_buffers (BufferSet& bufs,
541                                jack_nframes_t start_frame, jack_nframes_t end_frame, 
542                                jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
543                                bool meter)
544 {
545         // There's no such thing as a MIDI bus for the time being, to avoid diverging from trunk
546         // too much until the SoC settles down.  We'll do all the MIDI route work here for now
547         
548         // Main output stage is the only stage we've got.
549         // I think it's a pretty good stage though, wouldn't you say?
550         
551         if (muted()) {
552
553                 IO::silence(nframes, offset);
554
555         } else {
556
557                 deliver_output(bufs, start_frame, end_frame, nframes, offset);
558
559         }
560
561 }
562
563 int
564 MidiTrack::set_name (string str, void *src)
565 {
566         int ret;
567
568         if (record_enabled() && _session.actively_recording()) {
569                 /* this messes things up if done while recording */
570                 return -1;
571         }
572
573         if (_diskstream->set_name (str)) {
574                 return -1;
575         }
576
577         /* save state so that the statefile fully reflects any filename changes */
578
579         if ((ret = IO::set_name (str, src)) == 0) {
580                 _session.save_state ("");
581         }
582         return ret;
583 }
584
585 int
586 MidiTrack::export_stuff (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t end_frame)
587 {
588         return -1;
589 }
590
591 void
592 MidiTrack::set_latency_delay (jack_nframes_t longest_session_latency)
593 {
594         Route::set_latency_delay (longest_session_latency);
595         _diskstream->set_roll_delay (_roll_delay);
596 }
597
598 void
599 MidiTrack::bounce (InterThreadInfo& itt)
600 {
601         throw;
602         //vector<MidiSource*> srcs;
603         //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
604 }
605
606
607 void
608 MidiTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
609 {
610         throw;
611         //vector<MidiSource*> srcs;
612         //_session.write_one_midi_track (*this, start, end, false, srcs, itt);
613 }
614
615 void
616 MidiTrack::freeze (InterThreadInfo& itt)
617 {
618 }
619
620 void
621 MidiTrack::unfreeze ()
622 {
623         _freeze_record.state = UnFrozen;
624         FreezeChange (); /* EMIT SIGNAL */
625 }
626
627 void
628 MidiTrack::set_mode (TrackMode m)
629 {
630         if (_diskstream) {
631                 if (_mode != m) {
632                         _mode = m;
633                         _diskstream->set_destructive (m == Destructive);
634                         ModeChanged();
635                 }
636         }
637 }