Merge branch 'master' into cairocanvas
[ardour.git] / libs / midi++2 / midi++ / mmc.h
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 */
19
20 #ifndef __midipp_mmc_h_h__
21 #define __midipp_mmc_h_h__
22
23 #include "timecode/time.h"
24
25 #include "pbd/signals.h"
26 #include "pbd/ringbuffer.h"
27
28 #include "midi++/libmidi_visibility.h"
29 #include "midi++/types.h"
30 #include "midi++/parser.h"
31
32 namespace ARDOUR {
33         class PortEngine;
34 }
35
36 namespace MIDI {
37
38 class Port;
39 class Parser;
40 class MachineControlCommand;
41
42 /** Class to handle incoming and outgoing MIDI machine control messages */
43 class LIBMIDIPP_API MachineControl 
44 {
45   public:
46         typedef PBD::Signal1<void,MachineControl&> MMCSignal;
47
48         enum Command {
49                 cmdStop = 0x1,
50                 cmdPlay = 0x2,
51                 cmdDeferredPlay = 0x3,
52                 cmdFastForward = 0x4,
53                 cmdRewind = 0x5,
54                 cmdRecordStrobe = 0x6,
55
56                 cmdRecordExit = 0x7,
57                 cmdRecordPause = 0x8,
58                 cmdPause = 0x9,
59                 cmdEject = 0xA,
60                 cmdChase = 0xB,
61                 cmdCommandErrorReset = 0xC,
62                 cmdMmcReset = 0xD,
63                 
64                 cmdIllegalMackieJogStart = 0x20,
65                 cmdIllegalMackieJogStop = 0x21,
66                 
67                 cmdWrite = 0x40,
68                 cmdMaskedWrite = 0x41,
69                 cmdRead = 0x42,
70                 cmdUpdate = 0x43,
71                 cmdLocate = 0x44,
72                 cmdVariablePlay = 0x45,
73                 cmdSearch = 0x46,
74
75                 cmdShuttle = 0x47,
76                 cmdStep = 0x48,
77                 cmdAssignSystemMaster = 0x49,
78                 cmdGeneratorCommand = 0x4A,
79                 cmdMtcCommand = 0x4B,
80                 cmdMove = 0x4C,
81                 cmdAdd = 0x4D,
82
83                 cmdSubtract = 0x4E,
84                 cmdDropFrameAdjust = 0x4F,
85                 cmdProcedure = 0x50,
86                 cmdEvent = 0x51,
87                 cmdGroup = 0x52,
88                 cmdCommandSegment = 0x53,
89                 cmdDeferredVariablePlay = 0x54,
90
91                 cmdRecordStrobeVariable = 0x55,
92
93                 cmdWait = 0x7C,
94                 cmdResume = 0x7F
95         };
96         
97         MachineControl ();
98     
99         void set_ports (MIDI::Port* input, MIDI::Port* output);
100
101         Port* input_port() { return _input_port; }
102         Port* output_port() { return _output_port; }
103         
104         void set_receive_device_id (byte id);
105         void set_send_device_id (byte id);
106         byte receive_device_id () const { return _receive_device_id; }
107         byte send_device_id () const { return _send_device_id; }
108         void enable_send (bool);
109         bool send_enabled () const { return _enable_send; }
110         void send (MachineControlCommand const &);
111
112         static bool is_mmc (byte *sysex_buf, size_t len);
113
114         /* Signals to connect to if you want to run "callbacks"
115            when certain MMC commands are received.
116         */
117                         
118         MMCSignal Stop;
119         MMCSignal Play;
120         MMCSignal DeferredPlay;
121         MMCSignal FastForward;
122         MMCSignal Rewind;
123         MMCSignal RecordStrobe;
124         MMCSignal RecordExit;
125         MMCSignal RecordPause;
126         MMCSignal Pause;
127         MMCSignal Eject;
128         MMCSignal Chase;
129         MMCSignal CommandErrorReset;
130         MMCSignal MmcReset;
131         MMCSignal JogStart;
132         MMCSignal JogStop;
133         MMCSignal Write;
134         MMCSignal MaskedWrite;
135         MMCSignal Read;
136         MMCSignal Update;
137         MMCSignal VariablePlay;
138         MMCSignal Search;
139         MMCSignal AssignSystemMaster;
140         MMCSignal GeneratorCommand;
141         MMCSignal MidiTimeCodeCommand;
142         MMCSignal Move;
143         MMCSignal Add;
144         MMCSignal Subtract;
145         MMCSignal DropFrameAdjust;
146         MMCSignal Procedure;
147         MMCSignal Event;
148         MMCSignal Group;
149         MMCSignal CommandSegment;
150         MMCSignal DeferredVariablePlay;
151         MMCSignal RecordStrobeVariable;
152         MMCSignal Wait;
153         MMCSignal Resume;
154
155         PBD::Signal0<void> SPPStart;
156         PBD::Signal0<void> SPPContinue;
157         PBD::Signal0<void> SPPStop;
158
159         /* The second argument is the shuttle speed, the third is
160            true if the direction is "forwards", false for "reverse"
161         */
162         
163         PBD::Signal3<void,MachineControl&,float,bool> Shuttle;
164
165         /* The second argument specifies the desired track record enabled
166            status.
167         */
168
169         PBD::Signal3<void,MachineControl &,size_t,bool> 
170                                              TrackRecordStatusChange;
171         
172         /* The second argument specifies the desired track record enabled
173            status.
174         */
175
176         PBD::Signal3<void,MachineControl &,size_t,bool> 
177                                              TrackMuteChange;
178         
179         /* The second argument points to a byte array containing
180            the locate target value in MMC Standard Time Code
181            format (5 bytes, roughly: hrs/mins/secs/frames/subframes)
182         */
183
184         PBD::Signal2<void,MachineControl &, const byte *> Locate;
185
186         /* The second argument is the number of steps to jump */
187         
188         PBD::Signal2<void,MachineControl &, int> Step;
189
190 #define MMC_NTRACKS 48
191
192         /* note: these are not currently in use */
193         
194         byte updateRate;
195         byte responseError;
196         byte commandError;
197         byte commandErrorLevel;
198
199         byte motionControlTally;
200         byte velocityTally;
201         byte stopMode;
202         byte fastMode;
203         byte recordMode;
204         byte recordStatus;
205         bool trackRecordStatus[MMC_NTRACKS];
206         bool trackRecordReady[MMC_NTRACKS];
207         byte globalMonitor;
208         byte recordMonitor;
209         byte trackSyncMonitor;
210         byte trackInputMonitor;
211         byte stepLength;
212         byte playSpeedReference;
213         byte fixedSpeed;
214         byte lifterDefeat;
215         byte controlDisable;
216         byte trackMute[MMC_NTRACKS];
217         byte failure;
218         byte selectedTimeCode;
219         byte shortSelectedTimeCode;
220         byte timeStandard;
221         byte selectedTimeCodeSource;
222         byte selectedTimeCodeUserbits;
223         byte selectedMasterCode;
224         byte requestedOffset;
225         byte actualOffset;
226         byte lockDeviation;
227         byte shortSelectedMasterCode;
228         byte shortRequestedOffset;
229         byte shortActualOffset;
230         byte shortLockDeviation;
231         byte resolvedPlayMode;
232         byte chaseMode;
233         byte generatorTimeCode;
234         byte shortGeneratorTimeCode;
235         byte generatorCommandTally;
236         byte generatorSetUp;
237         byte generatorUserbits;
238         byte vitcInsertEnable;
239         byte midiTimeCodeInput;
240         byte shortMidiTimeCodeInput;
241         byte midiTimeCodeCommandTally;
242         byte midiTimeCodeSetUp;
243         byte gp0;
244         byte gp1;
245         byte gp2;
246         byte gp3;
247         byte gp4;
248         byte gp5;
249         byte gp6;
250         byte gp7;
251         byte shortGp0;
252         byte shortGp1;
253         byte shortGp2;
254         byte shortGp3;
255         byte shortGp4;
256         byte shortGp5;
257         byte shortGp6;
258         byte shortGp7;
259         byte procedureResponse;
260         byte eventResponse;
261         byte responseSegment;
262         byte wait;
263         byte resume;
264         
265   private:
266         byte _receive_device_id;
267         byte _send_device_id;
268         Port* _input_port;
269         Port* _output_port;
270         bool _enable_send; ///< true if MMC sending is enabled
271
272         void process_mmc_message (Parser &p, byte *, size_t len);
273         PBD::ScopedConnectionList port_connections; ///< connections to our parser for incoming data
274
275         int  do_masked_write (byte *, size_t len);
276         int  do_locate (byte *, size_t len);
277         int  do_step (byte *, size_t len);
278         int  do_shuttle (byte *, size_t len);
279         
280         void write_track_status (byte *, size_t len, byte reg);
281         void spp_start ();
282         void spp_continue ();
283         void spp_stop ();
284 };
285
286 /** Class to describe a MIDI machine control command to be sent.
287  *  In an ideal world we might use a class hierarchy for this, but objects of this type
288  *  have to be allocated off the stack for RT safety.
289  */
290 class LIBMIDIPP_API MachineControlCommand
291 {
292 public:
293         MachineControlCommand () : _command (MachineControl::Command (0)) {}
294         MachineControlCommand (MachineControl::Command);
295         MachineControlCommand (Timecode::Time);
296         
297         MIDI::byte* fill_buffer (MachineControl *mmc, MIDI::byte *) const;
298
299 private:
300         MachineControl::Command _command;
301         Timecode::Time _time;
302 };
303
304 } // namespace MIDI
305
306 #endif /* __midipp_mmc_h_h__ */