convert codebase to use Temporal for various time types
[ardour.git] / libs / midi++2 / midi++ / mmc.h
index 5b3bc663e6c03d5f4224d2a0e9cc85d7b4ce6732..b69abaa8a5431a9ea34aad69261f6975b910f5f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2000 Paul Barton-Davis 
+    Copyright (C) 2000 Paul Barton-Davis
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #ifndef __midipp_mmc_h_h__
 #define __midipp_mmc_h_h__
 
-#include "control_protocol/timecode.h"
+#include "temporal/time.h"
+
 #include "pbd/signals.h"
 #include "pbd/ringbuffer.h"
+
+#include "midi++/libmidi_visibility.h"
 #include "midi++/types.h"
+#include "midi++/parser.h"
+
+namespace ARDOUR {
+       class PortEngine;
+}
 
 namespace MIDI {
 
 class Port;
 class Parser;
-class MachineControlCommand;   
+class MachineControlCommand;
 
 /** Class to handle incoming and outgoing MIDI machine control messages */
-class MachineControl 
+class LIBMIDIPP_API MachineControl
 {
   public:
        typedef PBD::Signal1<void,MachineControl&> MMCSignal;
@@ -52,10 +60,10 @@ class MachineControl
                cmdChase = 0xB,
                cmdCommandErrorReset = 0xC,
                cmdMmcReset = 0xD,
-               
+
                cmdIllegalMackieJogStart = 0x20,
                cmdIllegalMackieJogStop = 0x21,
-               
+
                cmdWrite = 0x40,
                cmdMaskedWrite = 0x41,
                cmdRead = 0x42,
@@ -85,27 +93,28 @@ class MachineControl
                cmdWait = 0x7C,
                cmdResume = 0x7F
        };
-       
-       MachineControl ();
-       void set_port (Port* p);
 
-       Port* port() { return _port; }
-       
+        MachineControl ();
+
+        void set_ports (MIDI::Port* input, MIDI::Port* output);
+
+       Port* input_port() { return _input_port; }
+       Port* output_port() { return _output_port; }
+
        void set_receive_device_id (byte id);
        void set_send_device_id (byte id);
        byte receive_device_id () const { return _receive_device_id; }
        byte send_device_id () const { return _send_device_id; }
        void enable_send (bool);
-       void send (MachineControlCommand const &);
-       void flush_pending ();
+       bool send_enabled () const { return _enable_send; }
+       void send (MachineControlCommand const &, timestamp_t when);
 
        static bool is_mmc (byte *sysex_buf, size_t len);
-       static void set_sending_thread (pthread_t);
 
        /* Signals to connect to if you want to run "callbacks"
           when certain MMC commands are received.
        */
-                       
+
        MMCSignal Stop;
        MMCSignal Play;
        MMCSignal DeferredPlay;
@@ -143,74 +152,148 @@ class MachineControl
        MMCSignal Wait;
        MMCSignal Resume;
 
+       PBD::Signal0<void> SPPStart;
+       PBD::Signal0<void> SPPContinue;
+       PBD::Signal0<void> SPPStop;
+
        /* The second argument is the shuttle speed, the third is
           true if the direction is "forwards", false for "reverse"
        */
-       
+
        PBD::Signal3<void,MachineControl&,float,bool> Shuttle;
 
        /* The second argument specifies the desired track record enabled
           status.
        */
 
-       PBD::Signal3<void,MachineControl &,size_t,bool> 
+       PBD::Signal3<void,MachineControl &,size_t,bool>
                                             TrackRecordStatusChange;
-       
+
        /* The second argument specifies the desired track record enabled
           status.
        */
 
-       PBD::Signal3<void,MachineControl &,size_t,bool> 
+       PBD::Signal3<void,MachineControl &,size_t,bool>
                                             TrackMuteChange;
-       
+
        /* The second argument points to a byte array containing
           the locate target value in MMC Standard Time Code
-          format (5 bytes, roughly: hrs/mins/secs/frames/subframes)
+          format (5 bytes, roughly: hrs/mins/secs/samples/subframes)
        */
 
        PBD::Signal2<void,MachineControl &, const byte *> Locate;
 
        /* The second argument is the number of steps to jump */
-       
+
        PBD::Signal2<void,MachineControl &, int> Step;
-       
+
+#define MMC_NTRACKS 48
+
+       /* note: these are not currently in use */
+
+       byte updateRate;
+       byte responseError;
+       byte commandError;
+       byte commandErrorLevel;
+
+       byte motionControlTally;
+       byte velocityTally;
+       byte stopMode;
+       byte fastMode;
+       byte recordMode;
+       byte recordStatus;
+       bool trackRecordStatus[MMC_NTRACKS];
+       bool trackRecordReady[MMC_NTRACKS];
+       byte globalMonitor;
+       byte recordMonitor;
+       byte trackSyncMonitor;
+       byte trackInputMonitor;
+       byte stepLength;
+       byte playSpeedReference;
+       byte fixedSpeed;
+       byte lifterDefeat;
+       byte controlDisable;
+       byte trackMute[MMC_NTRACKS];
+       byte failure;
+       byte selectedTimeCode;
+       byte shortSelectedTimeCode;
+       byte timeStandard;
+       byte selectedTimeCodeSource;
+       byte selectedTimeCodeUserbits;
+       byte selectedMasterCode;
+       byte requestedOffset;
+       byte actualOffset;
+       byte lockDeviation;
+       byte shortSelectedMasterCode;
+       byte shortRequestedOffset;
+       byte shortActualOffset;
+       byte shortLockDeviation;
+       byte resolvedPlayMode;
+       byte chaseMode;
+       byte generatorTimeCode;
+       byte shortGeneratorTimeCode;
+       byte generatorCommandTally;
+       byte generatorSetUp;
+       byte generatorUserbits;
+       byte vitcInsertEnable;
+       byte midiTimeCodeInput;
+       byte shortMidiTimeCodeInput;
+       byte midiTimeCodeCommandTally;
+       byte midiTimeCodeSetUp;
+       byte gp0;
+       byte gp1;
+       byte gp2;
+       byte gp3;
+       byte gp4;
+       byte gp5;
+       byte gp6;
+       byte gp7;
+       byte shortGp0;
+       byte shortGp1;
+       byte shortGp2;
+       byte shortGp3;
+       byte shortGp4;
+       byte shortGp5;
+       byte shortGp6;
+       byte shortGp7;
+       byte procedureResponse;
+       byte eventResponse;
+       byte responseSegment;
+       byte wait;
+       byte resume;
+
   private:
        byte _receive_device_id;
        byte _send_device_id;
-       Port* _port;
+       Port* _input_port;
+       Port* _output_port;
        bool _enable_send; ///< true if MMC sending is enabled
 
-       /** A ringbuffer of MMC commands that were `sent' from the wrong thread, which
-           are queued up and sent when flush_pending() is called.
-       */
-       RingBuffer<MachineControlCommand> _pending;
-
-       /** The thread to use for sending MMC commands */
-       static pthread_t _sending_thread;
-
        void process_mmc_message (Parser &p, byte *, size_t len);
-       PBD::ScopedConnection mmc_connection; ///< connection to our parser for incoming data
+       PBD::ScopedConnectionList port_connections; ///< connections to our parser for incoming data
 
        int  do_masked_write (byte *, size_t len);
        int  do_locate (byte *, size_t len);
        int  do_step (byte *, size_t len);
        int  do_shuttle (byte *, size_t len);
-       void send_immediately (MachineControlCommand const &);
-       
+
        void write_track_status (byte *, size_t len, byte reg);
+       void spp_start ();
+       void spp_continue ();
+       void spp_stop ();
 };
 
 /** Class to describe a MIDI machine control command to be sent.
  *  In an ideal world we might use a class hierarchy for this, but objects of this type
- *  have to be allocated off the stack for thread safety.
+ *  have to be allocated off the stack for RT safety.
  */
-class MachineControlCommand
+class LIBMIDIPP_API MachineControlCommand
 {
 public:
        MachineControlCommand () : _command (MachineControl::Command (0)) {}
        MachineControlCommand (MachineControl::Command);
        MachineControlCommand (Timecode::Time);
-       
+
        MIDI::byte* fill_buffer (MachineControl *mmc, MIDI::byte *) const;
 
 private: