convert codebase to use Temporal for various time types
[ardour.git] / libs / midi++2 / midi++ / mmc.h
index bc23beb0a1e6cf6410cef662a6913aa4ca6ccc0d..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 <sigc++/sigc++.h>
-#include <midi++/types.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 MachineControl : public sigc::trackable
-
+/** Class to handle incoming and outgoing MIDI machine control messages */
+class LIBMIDIPP_API MachineControl
 {
   public:
-       typedef byte CommandSignature[60];
-       typedef byte ResponseSignature[60];
+       typedef PBD::Signal1<void,MachineControl&> MMCSignal;
 
        enum Command {
                cmdStop = 0x1,
@@ -50,10 +60,10 @@ class MachineControl : public sigc::trackable
                cmdChase = 0xB,
                cmdCommandErrorReset = 0xC,
                cmdMmcReset = 0xD,
-               
+
                cmdIllegalMackieJogStart = 0x20,
                cmdIllegalMackieJogStop = 0x21,
-               
+
                cmdWrite = 0x40,
                cmdMaskedWrite = 0x41,
                cmdRead = 0x42,
@@ -83,100 +93,109 @@ class MachineControl : public sigc::trackable
                cmdWait = 0x7C,
                cmdResume = 0x7F
        };
-       
-       MachineControl (Port &port,
-                       float MMCVersion, 
-                       CommandSignature &cs,
-                       ResponseSignature &rs);
 
-       Port &port() { return _port; }
-       
-       void set_device_id (byte id);
-       byte device_id () const { return _device_id; }
+        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);
+       bool send_enabled () const { return _enable_send; }
+       void send (MachineControlCommand const &, timestamp_t when);
 
        static bool is_mmc (byte *sysex_buf, size_t len);
 
        /* Signals to connect to if you want to run "callbacks"
           when certain MMC commands are received.
        */
-                       
-       sigc::signal<void,MachineControl &> Stop;
-       sigc::signal<void,MachineControl &> Play;
-       sigc::signal<void,MachineControl &> DeferredPlay;
-       sigc::signal<void,MachineControl &> FastForward;
-       sigc::signal<void,MachineControl &> Rewind;
-       sigc::signal<void,MachineControl &> RecordStrobe;
-       sigc::signal<void,MachineControl &> RecordExit;
-       sigc::signal<void,MachineControl &> RecordPause;
-       sigc::signal<void,MachineControl &> Pause;
-       sigc::signal<void,MachineControl &> Eject;
-       sigc::signal<void,MachineControl &> Chase;
-       sigc::signal<void,MachineControl &> CommandErrorReset;
-       sigc::signal<void,MachineControl &> MmcReset;
-
-       sigc::signal<void,MachineControl &> JogStart;
-       sigc::signal<void,MachineControl &> JogStop;
-
-       sigc::signal<void,MachineControl &> Write;
-       sigc::signal<void,MachineControl &> MaskedWrite;
-       sigc::signal<void,MachineControl &> Read;
-       sigc::signal<void,MachineControl &> Update;
-       sigc::signal<void,MachineControl &> VariablePlay;
-       sigc::signal<void,MachineControl &> Search;
-       sigc::signal<void,MachineControl &> AssignSystemMaster;
-       sigc::signal<void,MachineControl &> GeneratorCommand;
-       sigc::signal<void,MachineControl &> MidiTimeCodeCommand;
-       sigc::signal<void,MachineControl &> Move;
-       sigc::signal<void,MachineControl &> Add;
-       sigc::signal<void,MachineControl &> Subtract;
-       sigc::signal<void,MachineControl &> DropFrameAdjust;
-       sigc::signal<void,MachineControl &> Procedure;
-       sigc::signal<void,MachineControl &> Event;
-       sigc::signal<void,MachineControl &> Group;
-       sigc::signal<void,MachineControl &> CommandSegment;
-       sigc::signal<void,MachineControl &> DeferredVariablePlay;
-       sigc::signal<void,MachineControl &> RecordStrobeVariable;
-       sigc::signal<void,MachineControl &> Wait;
-       sigc::signal<void,MachineControl &> Resume;
+
+       MMCSignal Stop;
+       MMCSignal Play;
+       MMCSignal DeferredPlay;
+       MMCSignal FastForward;
+       MMCSignal Rewind;
+       MMCSignal RecordStrobe;
+       MMCSignal RecordExit;
+       MMCSignal RecordPause;
+       MMCSignal Pause;
+       MMCSignal Eject;
+       MMCSignal Chase;
+       MMCSignal CommandErrorReset;
+       MMCSignal MmcReset;
+       MMCSignal JogStart;
+       MMCSignal JogStop;
+       MMCSignal Write;
+       MMCSignal MaskedWrite;
+       MMCSignal Read;
+       MMCSignal Update;
+       MMCSignal VariablePlay;
+       MMCSignal Search;
+       MMCSignal AssignSystemMaster;
+       MMCSignal GeneratorCommand;
+       MMCSignal MidiTimeCodeCommand;
+       MMCSignal Move;
+       MMCSignal Add;
+       MMCSignal Subtract;
+       MMCSignal DropFrameAdjust;
+       MMCSignal Procedure;
+       MMCSignal Event;
+       MMCSignal Group;
+       MMCSignal CommandSegment;
+       MMCSignal DeferredVariablePlay;
+       MMCSignal RecordStrobeVariable;
+       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"
        */
-       
-       sigc::signal<void,MachineControl &,float,bool> Shuttle;
+
+       PBD::Signal3<void,MachineControl&,float,bool> Shuttle;
 
        /* The second argument specifies the desired track record enabled
           status.
        */
 
-       sigc::signal<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>
+                                            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)
        */
 
-       sigc::signal<void,MachineControl &, const byte *> Locate;
+       PBD::Signal2<void,MachineControl &, const byte *> Locate;
 
        /* The second argument is the number of steps to jump */
-       
-       sigc::signal<void,MachineControl &, int> Step;
-       
-  protected:
 
-#define MMC_NTRACKS 48
+       PBD::Signal2<void,MachineControl &, int> Step;
 
-       /* MMC Information fields (think "registers") */
+#define MMC_NTRACKS 48
 
-       CommandSignature commandSignature;
-       ResponseSignature responseSignature;
+       /* note: these are not currently in use */
 
        byte updateRate;
        byte responseError;
        byte commandError;
        byte commandErrorLevel;
-       
+
        byte motionControlTally;
        byte velocityTally;
        byte stopMode;
@@ -194,7 +213,7 @@ class MachineControl : public sigc::trackable
        byte fixedSpeed;
        byte lifterDefeat;
        byte controlDisable;
-       byte trackMute;
+       byte trackMute[MMC_NTRACKS];
        byte failure;
        byte selectedTimeCode;
        byte shortSelectedTimeCode;
@@ -244,17 +263,42 @@ class MachineControl : public sigc::trackable
        byte resume;
 
   private:
-       byte _device_id;
-       MIDI::Port &_port;
+       byte _receive_device_id;
+       byte _send_device_id;
+       Port* _input_port;
+       Port* _output_port;
+       bool _enable_send; ///< true if MMC sending is enabled
 
        void process_mmc_message (Parser &p, byte *, size_t len);
-       
+       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 write_track_record_ready (byte *, size_t len);
+       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 RT safety.
+ */
+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:
+       MachineControl::Command _command;
+       Timecode::Time _time;
 };
 
 } // namespace MIDI