2 Copyright (C) 2000 Paul Barton-Davis
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.
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.
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.
20 #ifndef __midipp_mmc_h_h__
21 #define __midipp_mmc_h_h__
23 #include "timecode/time.h"
25 #include "pbd/signals.h"
26 #include "pbd/ringbuffer.h"
28 #include "midi++/libmidi_visibility.h"
29 #include "midi++/types.h"
30 #include "midi++/parser.h"
40 class MachineControlCommand;
42 /** Class to handle incoming and outgoing MIDI machine control messages */
43 class LIBMIDIPP_API MachineControl
46 typedef PBD::Signal1<void,MachineControl&> MMCSignal;
51 cmdDeferredPlay = 0x3,
54 cmdRecordStrobe = 0x6,
61 cmdCommandErrorReset = 0xC,
64 cmdIllegalMackieJogStart = 0x20,
65 cmdIllegalMackieJogStop = 0x21,
68 cmdMaskedWrite = 0x41,
72 cmdVariablePlay = 0x45,
77 cmdAssignSystemMaster = 0x49,
78 cmdGeneratorCommand = 0x4A,
84 cmdDropFrameAdjust = 0x4F,
88 cmdCommandSegment = 0x53,
89 cmdDeferredVariablePlay = 0x54,
91 cmdRecordStrobeVariable = 0x55,
99 void set_ports (MIDI::Port* input, MIDI::Port* output);
101 Port* input_port() { return _input_port; }
102 Port* output_port() { return _output_port; }
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 &);
112 static bool is_mmc (byte *sysex_buf, size_t len);
114 /* Signals to connect to if you want to run "callbacks"
115 when certain MMC commands are received.
120 MMCSignal DeferredPlay;
121 MMCSignal FastForward;
123 MMCSignal RecordStrobe;
124 MMCSignal RecordExit;
125 MMCSignal RecordPause;
129 MMCSignal CommandErrorReset;
134 MMCSignal MaskedWrite;
137 MMCSignal VariablePlay;
139 MMCSignal AssignSystemMaster;
140 MMCSignal GeneratorCommand;
141 MMCSignal MidiTimeCodeCommand;
145 MMCSignal DropFrameAdjust;
149 MMCSignal CommandSegment;
150 MMCSignal DeferredVariablePlay;
151 MMCSignal RecordStrobeVariable;
155 PBD::Signal0<void> SPPStart;
156 PBD::Signal0<void> SPPContinue;
157 PBD::Signal0<void> SPPStop;
159 /* The second argument is the shuttle speed, the third is
160 true if the direction is "forwards", false for "reverse"
163 PBD::Signal3<void,MachineControl&,float,bool> Shuttle;
165 /* The second argument specifies the desired track record enabled
169 PBD::Signal3<void,MachineControl &,size_t,bool>
170 TrackRecordStatusChange;
172 /* The second argument specifies the desired track record enabled
176 PBD::Signal3<void,MachineControl &,size_t,bool>
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)
184 PBD::Signal2<void,MachineControl &, const byte *> Locate;
186 /* The second argument is the number of steps to jump */
188 PBD::Signal2<void,MachineControl &, int> Step;
190 #define MMC_NTRACKS 48
192 /* note: these are not currently in use */
197 byte commandErrorLevel;
199 byte motionControlTally;
205 bool trackRecordStatus[MMC_NTRACKS];
206 bool trackRecordReady[MMC_NTRACKS];
209 byte trackSyncMonitor;
210 byte trackInputMonitor;
212 byte playSpeedReference;
216 byte trackMute[MMC_NTRACKS];
218 byte selectedTimeCode;
219 byte shortSelectedTimeCode;
221 byte selectedTimeCodeSource;
222 byte selectedTimeCodeUserbits;
223 byte selectedMasterCode;
224 byte requestedOffset;
227 byte shortSelectedMasterCode;
228 byte shortRequestedOffset;
229 byte shortActualOffset;
230 byte shortLockDeviation;
231 byte resolvedPlayMode;
233 byte generatorTimeCode;
234 byte shortGeneratorTimeCode;
235 byte generatorCommandTally;
237 byte generatorUserbits;
238 byte vitcInsertEnable;
239 byte midiTimeCodeInput;
240 byte shortMidiTimeCodeInput;
241 byte midiTimeCodeCommandTally;
242 byte midiTimeCodeSetUp;
259 byte procedureResponse;
261 byte responseSegment;
266 byte _receive_device_id;
267 byte _send_device_id;
270 bool _enable_send; ///< true if MMC sending is enabled
272 void process_mmc_message (Parser &p, byte *, size_t len);
273 PBD::ScopedConnectionList port_connections; ///< connections to our parser for incoming data
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);
280 void write_track_status (byte *, size_t len, byte reg);
282 void spp_continue ();
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.
290 class LIBMIDIPP_API MachineControlCommand
293 MachineControlCommand () : _command (MachineControl::Command (0)) {}
294 MachineControlCommand (MachineControl::Command);
295 MachineControlCommand (Timecode::Time);
297 MIDI::byte* fill_buffer (MachineControl *mmc, MIDI::byte *) const;
300 MachineControl::Command _command;
301 Timecode::Time _time;
306 #endif /* __midipp_mmc_h_h__ */