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