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