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