Support loading MIDI note names in NoteGroup tags as well.
[ardour.git] / libs / midi++2 / mmc.cc
1 /*
2     Copyright (C) 2000 Paul Barton-Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <fcntl.h>
22 #include <map>
23
24 #include "timecode/time.h"
25 #include "pbd/error.h"
26 #include "midi++/mmc.h"
27 #include "midi++/port.h"
28 #include "midi++/jack_midi_port.h"
29 #include "midi++/parser.h"
30 #include "midi++/manager.h"
31
32 using namespace std;
33 using namespace MIDI;
34 using namespace PBD;
35
36 static std::map<int,string> mmc_cmd_map;
37 static void build_mmc_cmd_map ()
38 {
39         pair<int,string> newpair;
40
41         newpair.first = 0x1;
42         newpair.second = "Stop";
43         mmc_cmd_map.insert (newpair);
44
45         newpair.first = 0x2;
46         newpair.second = "Play";
47         mmc_cmd_map.insert (newpair);
48
49         newpair.first = 0x3;
50         newpair.second = "DeferredPlay";
51         mmc_cmd_map.insert (newpair);
52
53         newpair.first = 0x4;
54         newpair.second = "FastForward";
55         mmc_cmd_map.insert (newpair);
56
57         newpair.first = 0x5;
58         newpair.second = "Rewind";
59         mmc_cmd_map.insert (newpair);
60
61         newpair.first = 0x6;
62         newpair.second = "RecordStrobe";
63         mmc_cmd_map.insert (newpair);
64
65         newpair.first = 0x7;
66         newpair.second = "RecordExit";
67         mmc_cmd_map.insert (newpair);
68
69         newpair.first = 0x8;
70         newpair.second = "RecordPause";
71         mmc_cmd_map.insert (newpair);
72
73         newpair.first = 0x9;
74         newpair.second = "Pause";
75         mmc_cmd_map.insert (newpair);
76
77         newpair.first = 0xA;
78         newpair.second = "Eject";
79         mmc_cmd_map.insert (newpair);
80
81         newpair.first = 0xB;
82         newpair.second = "Chase";
83         mmc_cmd_map.insert (newpair);
84
85         newpair.first = 0xC;
86         newpair.second = "CommandErrorReset";
87         mmc_cmd_map.insert (newpair);
88
89         newpair.first = 0xD;
90         newpair.second = "MmcReset";
91         mmc_cmd_map.insert (newpair);
92
93         newpair.first = 0x20;
94         newpair.second = "Illegal Mackie Jog Start";
95         mmc_cmd_map.insert (newpair);
96
97         newpair.first = 0x21;
98         newpair.second = "Illegal Mackie Jog Stop";
99         mmc_cmd_map.insert (newpair);
100
101         newpair.first = 0x40;
102         newpair.second = "Write";
103         mmc_cmd_map.insert (newpair);
104
105         newpair.first = 0x41;
106         newpair.second = "MaskedWrite";
107         mmc_cmd_map.insert (newpair);
108
109         newpair.first = 0x42;
110         newpair.second = "Read";
111         mmc_cmd_map.insert (newpair);
112
113         newpair.first = 0x43;
114         newpair.second = "Update";
115         mmc_cmd_map.insert (newpair);
116
117         newpair.first = 0x44;
118         newpair.second = "Locate";
119         mmc_cmd_map.insert (newpair);
120
121         newpair.first = 0x45;
122         newpair.second = "VariablePlay";
123         mmc_cmd_map.insert (newpair);
124
125         newpair.first = 0x46;
126         newpair.second = "Search";
127         mmc_cmd_map.insert (newpair);
128
129         newpair.first = 0x47;
130         newpair.second = "Shuttle";
131         mmc_cmd_map.insert (newpair);
132
133         newpair.first = 0x48;
134         newpair.second = "Step";
135         mmc_cmd_map.insert (newpair);
136
137         newpair.first = 0x49;
138         newpair.second = "AssignSystemMaster";
139         mmc_cmd_map.insert (newpair);
140
141         newpair.first = 0x4A;
142         newpair.second = "GeneratorCommand";
143         mmc_cmd_map.insert (newpair);
144
145         newpair.first = 0x4B;
146         newpair.second = "MtcCommand";
147         mmc_cmd_map.insert (newpair);
148
149         newpair.first = 0x4C;
150         newpair.second = "Move";
151         mmc_cmd_map.insert (newpair);
152
153         newpair.first = 0x4D;
154         newpair.second = "Add";
155         mmc_cmd_map.insert (newpair);
156
157         newpair.first = 0x4E;
158         newpair.second = "Subtract";
159         mmc_cmd_map.insert (newpair);
160
161         newpair.first = 0x4F;
162         newpair.second = "DropFrameAdjust";
163         mmc_cmd_map.insert (newpair);
164
165         newpair.first = 0x50;
166         newpair.second = "Procedure";
167         mmc_cmd_map.insert (newpair);
168
169         newpair.first = 0x51;
170         newpair.second = "Event";
171         mmc_cmd_map.insert (newpair);
172
173         newpair.first = 0x52;
174         newpair.second = "Group";
175         mmc_cmd_map.insert (newpair);
176
177         newpair.first = 0x53;
178         newpair.second = "CommandSegment";
179         mmc_cmd_map.insert (newpair);
180
181         newpair.first = 0x54;
182         newpair.second = "DeferredVariablePlay";
183         mmc_cmd_map.insert (newpair);
184
185         newpair.first = 0x55;
186         newpair.second = "RecordStrobeVariable";
187         mmc_cmd_map.insert (newpair);
188
189         newpair.first = 0x7C;
190         newpair.second = "Wait";
191         mmc_cmd_map.insert (newpair);
192
193         newpair.first = 0x7F;
194         newpair.second = "Resume";
195         mmc_cmd_map.insert (newpair);
196 }
197
198
199 MachineControl::MachineControl (Manager* m, jack_client_t* jack)
200 {
201         build_mmc_cmd_map ();
202
203         _receive_device_id = 0x7f;
204         _send_device_id = 0x7f;
205
206         _input_port = m->add_port (new JackMIDIPort ("MMC in", Port::IsInput, jack));
207         _output_port = m->add_port (new JackMIDIPort ("MMC out", Port::IsOutput, jack));
208
209         _input_port->parser()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
210         _input_port->parser()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this));
211         _input_port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this));
212         _input_port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this));
213 }
214
215 void
216 MachineControl::set_receive_device_id (byte id)
217 {
218         _receive_device_id = id & 0x7f;
219 }
220
221 void
222 MachineControl::set_send_device_id (byte id)
223 {
224         _send_device_id = id & 0x7f;
225 }
226
227 bool
228 MachineControl::is_mmc (byte *sysex_buf, size_t len)
229 {
230         if (len < 4 || len > 48) {
231                 return false;
232         }
233
234         if (sysex_buf[1] != 0x7f) {
235                 return false;
236         }
237
238         if (sysex_buf[3] != 0x6 && /* MMC Command */
239             sysex_buf[3] != 0x7) { /* MMC Response */
240                 return false;
241         }
242         
243         return true;
244 }
245
246 void
247 MachineControl::process_mmc_message (Parser &, byte *msg, size_t len)
248 {
249         size_t skiplen;
250         byte *mmc_msg;
251         bool single_byte;
252
253         /* Reject if its not for us. 0x7f is the "all-call" device ID */
254
255         /* msg[0] = 0x7f (MMC sysex ID(
256            msg[1] = device ID
257            msg[2] = 0x6 (MMC command) or 0x7 (MMC response)
258            msg[3] = MMC command code
259            msg[4] = (typically) byte count for following part of command
260         */
261
262 #if 0
263         cerr << "*** me = " << (int) _receive_device_id << " MMC message: len = " << len << "\n\t";
264         for (size_t i = 0; i < len; i++) {
265                 cerr << hex << (int) msg[i] << dec << ' ';
266         }
267         cerr << endl;
268 #endif
269
270         if (msg[1] != 0x7f && msg[1] != _receive_device_id) {
271                 return;
272         }
273
274         mmc_msg = &msg[3];
275         len -= 3;
276
277         do {
278
279                 single_byte = false;
280
281                 /* this works for all non-single-byte "counted"
282                    commands. we set it to 1 for the exceptions.
283                 */
284
285                 std::map<int,string>::iterator x = mmc_cmd_map.find ((int)mmc_msg[0]);
286                 string cmdname = "unknown";
287
288                 if (x != mmc_cmd_map.end()) {
289                         cmdname = (*x).second;
290                 }
291
292 #if 0
293                 cerr << "+++ MMC type " 
294                      << hex
295                      << ((int) *mmc_msg)
296                      << dec
297                      << " \"" << cmdname << "\" "
298                      << " len = " << len
299                      << endl;
300 #endif
301
302                 switch (*mmc_msg) {
303
304                 /* SINGLE-BYTE, UNCOUNTED COMMANDS */
305
306                 case cmdStop:
307                         Stop (*this);
308                         single_byte = true;
309                         break;
310
311                 case cmdPlay:
312                         Play (*this);
313                         single_byte = true;
314                         break;
315
316                 case cmdDeferredPlay:
317                         DeferredPlay (*this);
318                         single_byte = true;
319                         break;
320
321                 case cmdFastForward:
322                         FastForward (*this);
323                         single_byte = true;
324                         break;
325
326                 case cmdRewind:
327                         Rewind (*this);
328                         single_byte = true;
329                         break;
330
331                 case cmdRecordStrobe:
332                         RecordStrobe (*this);
333                         single_byte = true;
334                         break;
335
336                 case cmdRecordExit:
337                         RecordExit (*this);
338                         single_byte = true;
339                         break;
340
341                 case cmdRecordPause:
342                         RecordPause (*this);
343                         single_byte = true;
344                         break;
345
346                 case cmdPause:
347                         Pause (*this);
348                         single_byte = true;
349                         break;
350
351                 case cmdEject:
352                         Eject (*this);
353                         single_byte = true;
354                         break;
355
356                 case cmdChase:
357                         Chase (*this);
358                         single_byte = true;
359                         break;
360
361                 case cmdCommandErrorReset:
362                         CommandErrorReset (*this);
363                         single_byte = true;
364                         break;
365
366                 case cmdMmcReset:
367                         MmcReset (*this);
368                         single_byte = true;
369                         break;
370
371                 case cmdIllegalMackieJogStart:
372                         JogStart (*this);
373                         single_byte = true;
374                         break;
375
376                 case cmdIllegalMackieJogStop:
377                         JogStop (*this);
378                         single_byte = true;
379                         break;
380
381                 /* END OF SINGLE-BYTE, UNCOUNTED COMMANDS */
382
383                 case cmdMaskedWrite:
384                         do_masked_write (mmc_msg, len);
385                         break;
386
387                 case cmdLocate:
388                         do_locate (mmc_msg, len);
389                         break;
390
391                 case cmdShuttle:
392                         do_shuttle (mmc_msg, len);
393                         break;
394
395                 case cmdStep:
396                         do_step (mmc_msg, len);
397                         break;
398
399                 case cmdWrite:
400                 case cmdRead:
401                 case cmdUpdate:
402                 case cmdVariablePlay:
403                 case cmdSearch:
404                 case cmdAssignSystemMaster:
405                 case cmdGeneratorCommand:
406                 case cmdMtcCommand:
407                 case cmdMove:
408                 case cmdAdd:
409                 case cmdSubtract:
410                 case cmdDropFrameAdjust:
411                 case cmdProcedure:
412                 case cmdEvent:
413                 case cmdGroup:
414                 case cmdCommandSegment:
415                 case cmdDeferredVariablePlay:
416                 case cmdRecordStrobeVariable:
417                 case cmdWait:
418                 case cmdResume:
419                         error << "MIDI::MachineControl: unimplemented MMC command "
420                               << hex << (int) *mmc_msg << dec
421                               << endmsg;
422
423                         break;
424
425                 default:
426                         error << "MIDI::MachineControl: unknown MMC command "
427                               << hex << (int) *mmc_msg << dec
428                               << endmsg;
429
430                         break;
431                 }
432
433                 /* increase skiplen to cover the command byte and 
434                    count byte (if it existed).
435                 */
436
437                 if (!single_byte) {
438                         skiplen = mmc_msg[1] + 2;
439                 } else {
440                         skiplen = 1;
441                 }
442
443                 if (len <= skiplen) {
444                         break;
445                 }
446
447                 mmc_msg += skiplen;
448                 len -= skiplen;
449
450         } while (len > 1); /* skip terminating EOX byte */
451 }               
452
453 int
454 MachineControl::do_masked_write (byte *msg, size_t len)
455 {
456         /* return the number of bytes "consumed" */
457
458         int retval = msg[1] + 2; /* bytes following + 2 */
459         
460         switch (msg[2]) {
461         case 0x4f:  /* Track Record Ready Status */
462                 write_track_status (&msg[3], len - 3, msg[2]);
463                 break;
464
465         case 0x62: /* track mute */
466                 write_track_status (&msg[3], len - 3, msg[2]);
467                 break;
468
469         default:
470                 warning << "MIDI::MachineControl: masked write to "
471                         << hex << (int) msg[2] << dec
472                         << " not implemented"
473                         << endmsg;
474         }
475
476         return retval;
477 }
478
479 void
480 MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg)
481 {
482         size_t n;
483         ssize_t base_track;
484
485         /* Bits 0-4 of the first byte are for special tracks:
486
487            bit 0: video
488            bit 1: reserved
489            bit 2: time code
490            bit 3: aux track a
491            bit 4: aux track b
492
493            the format of the message (its an MMC Masked Write) is:
494            
495            0x41      Command Code
496            <count>   byte count of following data
497            <name>    byte value of the field being written
498            <byte #>  byte number of target byte in the 
499            bitmap being written to
500            <mask>    ones in the mask indicate which bits will be changed
501            <data>    new data for the byte being written
502            
503            by the time this code is executing, msg[0] is the
504            byte number of the target byte. if its zero, we
505            are writing to a special byte in the standard
506            track bitmap, in which the first 5 bits are
507            special. hence the bits for tracks 1 + 2 are bits
508            5 and 6 of the first byte of the track
509            bitmap. so:
510            
511            change track 1:  msg[0] = 0;       << first byte of track bitmap 
512                             msg[1] = 0100000; << binary: bit 5 set
513         
514            change track 2:  msg[0] = 0;       << first byte of track bitmap
515                             msg[1] = 1000000; << binary: bit 6 set
516         
517            change track 3:  msg[0] = 1;       << second byte of track bitmap
518                             msg[1] = 0000001; << binary: bit 0 set
519         
520            the (msg[0] * 8) - 6 computation is an attempt to
521            extract the value of the first track: ie. the one
522            that would be indicated by bit 0 being set.
523                 
524            so, if msg[0] = 0, msg[1] = 0100000 (binary),
525            what happens is that base_track = -5, but by the
526            time we check the correct bit, n = 5, and so the
527            computed track for the status change is 0 (first
528            track).
529
530            if msg[0] = 1, then the base track for any change is 2 (the third track), and so on.
531         */
532
533         /* XXX check needed to make sure we don't go outside the
534            supported number of tracks.
535         */
536
537         if (msg[0] == 0) {
538                 base_track = -5;
539         } else {
540                 base_track = (msg[0] * 8) - 6;
541         }
542
543         for (n = 0; n < 7; n++) {
544                 if (msg[1] & (1<<n)) {
545
546                         /* Only touch tracks that have the "mask"
547                            bit set.
548                         */
549
550                         bool val = (msg[2] & (1<<n));
551                         
552                         switch (reg) {
553                         case 0x4f:
554                                 trackRecordStatus[base_track+n] = val;
555                                 TrackRecordStatusChange (*this, base_track+n, val);
556                                 break;
557                                 
558                         case 0x62:
559                                 trackMute[base_track+n] = val;
560                                 TrackMuteChange (*this, base_track+n, val);
561                                 break;
562                         }
563                 } 
564
565         }
566 }
567
568 int
569 MachineControl::do_locate (byte *msg, size_t /*msglen*/)
570 {
571         if (msg[2] == 0) {
572                 warning << "MIDI::MMC: locate [I/F] command not supported"
573                         << endmsg;
574                 return 0;
575         }
576
577         /* regular "target" locate command */
578
579         Locate (*this, &msg[3]);
580         return 0;
581 }
582
583 int
584 MachineControl::do_step (byte *msg, size_t /*msglen*/)
585 {
586         int steps = msg[2] & 0x3f;
587
588         if (msg[2] & 0x40) {
589                 steps = -steps;
590         }
591
592         Step (*this, steps);
593         return 0;
594 }
595
596 int
597 MachineControl::do_shuttle (byte *msg, size_t /*msglen*/)
598 {
599         size_t forward;
600         byte sh = msg[2];
601         byte sm = msg[3];
602         byte sl = msg[4];
603         size_t left_shift;
604         size_t integral;
605         size_t fractional;
606         float shuttle_speed;
607
608         if (sh & (1<<6)) {
609                 forward = false;
610         } else {
611                 forward = true;
612         }
613         
614         left_shift = (sh & 0x38);
615
616         integral = ((sh & 0x7) << left_shift) | (sm >> (7 - left_shift));
617         fractional = ((sm << left_shift) << 7) | sl;
618
619         shuttle_speed = integral + 
620                 ((float)fractional / (1 << (14 - left_shift)));
621
622         Shuttle (*this, shuttle_speed, forward);
623
624         return 0;
625 }
626
627 void
628 MachineControl::enable_send (bool yn)
629 {
630         _enable_send = yn;
631 }
632
633 /** Send a MMC command to a the MMC port.
634  *  @param c command.
635  */
636 void
637 MachineControl::send (MachineControlCommand const & c)
638 {
639         if (_output_port == 0 || !_enable_send) {
640                 // cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl;
641                 return;
642         }
643
644         MIDI::byte buffer[32];
645         MIDI::byte* b = c.fill_buffer (this, buffer);
646
647         if (_output_port->midimsg (buffer, b - buffer, 0)) {
648                 error << "MMC: cannot send command" << endmsg;
649         }
650 }
651
652 void
653 MachineControl::spp_start ()
654 {
655         SPPStart (); /* EMIT SIGNAL */
656 }
657
658 void
659 MachineControl::spp_continue ()
660 {
661         SPPContinue (); /* EMIT SIGNAL */
662 }
663
664 void
665 MachineControl::spp_stop ()
666 {
667         SPPStop (); /* EMIT SIGNAL */
668 }
669
670 MachineControlCommand::MachineControlCommand (MachineControl::Command c)
671         : _command (c)
672 {
673
674 }
675
676 MachineControlCommand::MachineControlCommand (Timecode::Time t)
677         : _command (MachineControl::cmdLocate)
678         , _time (t)
679 {
680
681 }
682
683 MIDI::byte * 
684 MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const
685 {
686         *b++ = 0xf0; // SysEx
687         *b++ = 0x7f; // Real-time SysEx ID for MMC
688         *b++ = mmc->send_device_id();
689         *b++ = 0x6; // MMC command
690
691         *b++ = _command;
692
693         if (_command == MachineControl::cmdLocate) {
694                 *b++ = 0x6; // byte count
695                 *b++ = 0x1; // "TARGET" subcommand
696                 *b++ = _time.hours;
697                 *b++ = _time.minutes;
698                 *b++ = _time.seconds;
699                 *b++ = _time.frames;
700                 *b++ = _time.subframes;
701         }
702
703         *b++ = 0xf7;
704
705         return b;
706 }
707