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 "control_protocol/timecode.h"
24 #include "pbd/signals.h"
25 #include "pbd/ringbuffer.h"
26 #include "midi++/types.h"
32 class MachineControlCommand;
34 /** Class to handle incoming and outgoing MIDI machine control messages */
38 typedef PBD::Signal1<void,MachineControl&> MMCSignal;
43 cmdDeferredPlay = 0x3,
46 cmdRecordStrobe = 0x6,
53 cmdCommandErrorReset = 0xC,
56 cmdIllegalMackieJogStart = 0x20,
57 cmdIllegalMackieJogStop = 0x21,
60 cmdMaskedWrite = 0x41,
64 cmdVariablePlay = 0x45,
69 cmdAssignSystemMaster = 0x49,
70 cmdGeneratorCommand = 0x4A,
76 cmdDropFrameAdjust = 0x4F,
80 cmdCommandSegment = 0x53,
81 cmdDeferredVariablePlay = 0x54,
83 cmdRecordStrobeVariable = 0x55,
90 void set_port (Port* p);
92 Port* port() { return _port; }
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 ();
102 static bool is_mmc (byte *sysex_buf, size_t len);
103 static void set_sending_thread (pthread_t);
105 /* Signals to connect to if you want to run "callbacks"
106 when certain MMC commands are received.
111 MMCSignal DeferredPlay;
112 MMCSignal FastForward;
114 MMCSignal RecordStrobe;
115 MMCSignal RecordExit;
116 MMCSignal RecordPause;
120 MMCSignal CommandErrorReset;
125 MMCSignal MaskedWrite;
128 MMCSignal VariablePlay;
130 MMCSignal AssignSystemMaster;
131 MMCSignal GeneratorCommand;
132 MMCSignal MidiTimeCodeCommand;
136 MMCSignal DropFrameAdjust;
140 MMCSignal CommandSegment;
141 MMCSignal DeferredVariablePlay;
142 MMCSignal RecordStrobeVariable;
146 /* The second argument is the shuttle speed, the third is
147 true if the direction is "forwards", false for "reverse"
150 PBD::Signal3<void,MachineControl&,float,bool> Shuttle;
152 /* The second argument specifies the desired track record enabled
156 PBD::Signal3<void,MachineControl &,size_t,bool>
157 TrackRecordStatusChange;
159 /* The second argument specifies the desired track record enabled
163 PBD::Signal3<void,MachineControl &,size_t,bool>
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)
171 PBD::Signal2<void,MachineControl &, const byte *> Locate;
173 /* The second argument is the number of steps to jump */
175 PBD::Signal2<void,MachineControl &, int> Step;
177 #define MMC_NTRACKS 48
179 /* note: these are not currently in use */
184 byte commandErrorLevel;
186 byte motionControlTally;
192 bool trackRecordStatus[MMC_NTRACKS];
193 bool trackRecordReady[MMC_NTRACKS];
196 byte trackSyncMonitor;
197 byte trackInputMonitor;
199 byte playSpeedReference;
203 byte trackMute[MMC_NTRACKS];
205 byte selectedTimeCode;
206 byte shortSelectedTimeCode;
208 byte selectedTimeCodeSource;
209 byte selectedTimeCodeUserbits;
210 byte selectedMasterCode;
211 byte requestedOffset;
214 byte shortSelectedMasterCode;
215 byte shortRequestedOffset;
216 byte shortActualOffset;
217 byte shortLockDeviation;
218 byte resolvedPlayMode;
220 byte generatorTimeCode;
221 byte shortGeneratorTimeCode;
222 byte generatorCommandTally;
224 byte generatorUserbits;
225 byte vitcInsertEnable;
226 byte midiTimeCodeInput;
227 byte shortMidiTimeCodeInput;
228 byte midiTimeCodeCommandTally;
229 byte midiTimeCodeSetUp;
246 byte procedureResponse;
248 byte responseSegment;
253 byte _receive_device_id;
254 byte _send_device_id;
256 bool _enable_send; ///< true if MMC sending is enabled
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.
261 RingBuffer<MachineControlCommand> _pending;
263 /** The thread to use for sending MMC commands */
264 static pthread_t _sending_thread;
266 void process_mmc_message (Parser &p, byte *, size_t len);
267 PBD::ScopedConnection mmc_connection; ///< connection to our parser for incoming data
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 &);
275 void write_track_status (byte *, size_t len, byte reg);
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 RT safety.
282 class MachineControlCommand
285 MachineControlCommand () : _command (MachineControl::Command (0)) {}
286 MachineControlCommand (MachineControl::Command);
287 MachineControlCommand (Timecode::Time);
289 MIDI::byte* fill_buffer (MachineControl *mmc, MIDI::byte *) const;
292 MachineControl::Command _command;
293 Timecode::Time _time;
298 #endif /* __midipp_mmc_h_h__ */