DummyBackend: implement port connect_callback()
[ardour.git] / libs / backends / dummy / dummy_audiobackend.h
index ad6035dccabadf9653c6cd70a34b36bc9bf99978..733bb5f78a6d78d7bc433bf2708e8087cb7a8eec 100644 (file)
 #include <stdint.h>
 #include <pthread.h>
 
+#include <boost/shared_ptr.hpp>
+
 #include "ardour/types.h"
 #include "ardour/audio_backend.h"
 
 namespace ARDOUR {
 
+class DummyAudioBackend;
+
+class DummyMidiEvent {
+       public:
+               DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size);
+               DummyMidiEvent (const DummyMidiEvent& other);
+               ~DummyMidiEvent ();
+               size_t size () const { return _size; };
+               pframes_t timestamp () const { return _timestamp; };
+               const unsigned char* const_data () const { return _data; };
+               unsigned char* data () { return _data; };
+               bool operator< (const DummyMidiEvent &other) const { return timestamp () < other.timestamp (); };
+       private:
+               size_t _size;
+               pframes_t _timestamp;
+               uint8_t *_data;
+};
+
+typedef std::vector<boost::shared_ptr<DummyMidiEvent> > DummyMidiBuffer;
+
+class DummyPort {
+       protected:
+               DummyPort (DummyAudioBackend &b, const std::string&, PortFlags);
+       public:
+               virtual ~DummyPort ();
+
+               const std::string& name () const { return _name; }
+               PortFlags flags () const { return _flags; }
+
+               int set_name (const std::string &name) { _name = name; return 0; }
+
+               virtual DataType type () const = 0;
+
+               bool is_input ()     const { return flags () & IsInput; }
+               bool is_output ()    const { return flags () & IsOutput; }
+               bool is_physical ()  const { return flags () & IsPhysical; }
+               bool is_terminal ()  const { return flags () & IsTerminal; }
+               bool is_connected () const { return _connections.size () != 0; }
+               bool is_connected (const DummyPort *port) const;
+               bool is_physically_connected () const;
+
+               const std::vector<DummyPort *>& get_connections () const { return _connections; }
+
+               int connect (DummyPort *port);
+               int disconnect (DummyPort *port);
+               void disconnect_all ();
+
+               virtual void* get_buffer (pframes_t nframes) = 0;
+
+               const LatencyRange& latency_range (bool for_playback) const
+               {
+                       return for_playback ? _playback_latency_range : _capture_latency_range;
+               }
+
+               void set_latency_range (const LatencyRange &latency_range, bool for_playback)
+               {
+                       if (for_playback)
+                       {
+                               _playback_latency_range = latency_range;
+                       }
+                       else
+                       {
+                               _capture_latency_range = latency_range;
+                       }
+               }
+
+       private:
+               DummyAudioBackend &_dummy_backend;
+               std::string _name;
+               const PortFlags _flags;
+               LatencyRange _capture_latency_range;
+               LatencyRange _playback_latency_range;
+               std::vector<DummyPort*> _connections;
+
+               void _connect (DummyPort* , bool);
+               void _disconnect (DummyPort* , bool);
+
+}; // class DummyPort
+
+class DummyAudioPort : public DummyPort {
+       public:
+               DummyAudioPort (DummyAudioBackend &b, const std::string&, PortFlags);
+               ~DummyAudioPort ();
+
+               DataType type () const { return DataType::AUDIO; };
+
+               Sample* buffer () { return _buffer; }
+               const Sample* const_buffer () const { return _buffer; }
+               void* get_buffer (pframes_t nframes);
+
+       private:
+               Sample _buffer[8192];
+}; // class DummyAudioPort
+
+class DummyMidiPort : public DummyPort {
+       public:
+               DummyMidiPort (DummyAudioBackend &b, const std::string&, PortFlags);
+               ~DummyMidiPort ();
+
+               DataType type () const { return DataType::MIDI; };
+
+               void* get_buffer (pframes_t nframes);
+               const DummyMidiBuffer const_buffer () const { return _buffer; }
+
+       private:
+               DummyMidiBuffer _buffer;
+}; // class DummyMidiPort
+
 class DummyAudioBackend : public AudioBackend {
+       friend class DummyPort;
        public:
-               DummyAudioBackend (AudioEngine& e);
+                DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info);
                ~DummyAudioBackend ();
 
                /* AUDIOBACKEND API */
@@ -168,12 +279,16 @@ class DummyAudioBackend : public AudioBackend {
                bool  _freewheeling;
 
                float  _samplerate;
-               size_t _audio_buffersize;
+               size_t _samples_per_period;
                float  _dsp_load;
+               static size_t _max_buffer_size;
 
                uint32_t _n_inputs;
                uint32_t _n_outputs;
 
+               uint32_t _n_midi_inputs;
+               uint32_t _n_midi_outputs;
+
                uint32_t _systemic_input_latency;
                uint32_t _systemic_output_latency;
 
@@ -193,6 +308,46 @@ class DummyAudioBackend : public AudioBackend {
                        ThreadData (DummyAudioBackend* e, boost::function<void ()> fp, size_t stacksz)
                                : engine (e) , f (fp) , stacksize (stacksz) {}
                };
+
+               /* port engine */
+               PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
+               int register_system_ports ();
+               void unregister_system_ports ();
+
+               std::vector<DummyPort *> _ports;
+
+
+               struct PortConnectData {
+                       std::string a;
+                       std::string b;
+                       bool c;
+
+                       PortConnectData (const std::string& a, const std::string& b, bool c)
+                               : a (a) , b (b) , c (c) {}
+               };
+
+               std::vector<PortConnectData *> _port_connection_queue;
+               pthread_mutex_t _port_callback_mutex;
+
+               void port_connect_callback (const std::string& a, const std::string& b, bool conn) {
+                       pthread_mutex_lock (&_port_callback_mutex);
+                       _port_connection_queue.push_back(new PortConnectData(a, b, conn));
+                       pthread_mutex_unlock (&_port_callback_mutex);
+               }
+
+               bool valid_port (PortHandle port) const {
+                       return std::find (_ports.begin (), _ports.end (), (DummyPort*)port) != _ports.end ();
+               }
+
+               DummyPort * find_port (const std::string& port_name) const {
+                       for (std::vector<DummyPort*>::const_iterator it = _ports.begin (); it != _ports.end (); ++it) {
+                               if ((*it)->name () == port_name) {
+                                       return *it;
+                               }
+                       }
+                       return NULL;
+               }
+
 }; // class DummyAudioBackend
 
 } // namespace