summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/port_engine.h
blob: 8dc35ec8f56fabe53ae94c067392f75968b224b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
    Copyright (C) 2013 Paul 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
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __libardour_port_engine_h__
#define __libardour_port_engine_h__

#include <vector>
#include <string>

#include <stdint.h>

#include "ardour/data_type.h"
#include "ardour/types.h"

namespace ARDOUR {

/** PortEngine is an abstract base class that defines the functionality
 * required by Ardour. 
 * 
 * A Port is basically an endpoint for a datastream (which can either be
 * continuous, like audio, or event-based, like MIDI). Ports have buffers
 * associated with them into which data can be written (if they are output
 * ports) and from which data can be read (if they input ports). Ports can be
 * connected together so that data written to an output port can be read from
 * an input port. These connections can be 1:1, 1:N OR N:1. 
 *
 * Ports may be associated with software only, or with hardware.  Hardware
 * related ports are often referred to as physical, and correspond to some
 * relevant physical entity on a hardware device, such as an audio jack or a
 * MIDI connector. Physical ports may be potentially asked to monitor their
 * inputs, though some implementations may not support this.
 *
 * Most physical ports will also be considered "terminal", which means that
 * data delivered there or read from there will go to or comes from a system
 * outside of the PortEngine implementation's control (e.g. the analog domain
 * for audio, or external MIDI devices for MIDI). Non-physical ports can also
 * be considered "terminal". For example, the output port of a software
 * synthesizer is a terminal port, because the data contained in its buffer
 * does not and cannot be considered to come from any other port - it is
 * synthesized by its owner.
 *
 * Ports also have latency associated with them. Each port has a playback
 * latency and a capture latency:
 *
 * <b>capture latency</b>: how long since the data read from the buffer of a
 *                  port arrived at at a terminal port.  The data will have
 *                  come from the "outside world" if the terminal port is also
 *                  physical, or will have been synthesized by the entity that
 *                  owns the terminal port.
 *                  
 * <b>playback latency</b>: how long until the data written to the buffer of
 *                   port will reach a terminal port.
 *
 *
 * For more detailed questions about the PortEngine API, consult the JACK API
 * documentation, on which this entire object is based.
 */

class PortEngine {
  public:
    PortEngine() {}
    virtual ~PortEngine();
    
    /* We use void* here so that the API can be defined for any implementation.
     * 
     * We could theoretically use a template (PortEngine<T>) and define
     * PortHandle as T, but this complicates the desired inheritance
     * pattern in which FooPortEngine handles things for the Foo API,
     * rather than being a derivative of PortEngine<Foo>.
    */
       
    typedef void* PortHandle;

    virtual bool  connected() const = 0;
    virtual void* private_handle() const = 0;

    virtual int         set_port_name (PortHandle, const std::string&) = 0;
    virtual std::string get_port_name (PortHandle) const = 0;
    virtual PortHandle* get_port_by_name (const std::string&) const = 0;

    virtual std::string make_port_name_relative (const std::string& name) const = 0;
    virtual std::string make_port_name_non_relative (const std::string& name) const = 0;
    virtual bool        port_is_mine (const std::string& fullname) const = 0;

    virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags) = 0;
    virtual void  unregister_port (PortHandle) = 0;

    virtual bool  connected (PortHandle) = 0;
    virtual bool  connected_to (PortHandle, const std::string&) = 0;
    virtual bool  physically_connected (PortHandle) = 0;

    virtual int   get_connections (PortHandle, std::vector<std::string>&) = 0;

    virtual int   connect (PortHandle, const std::string&) = 0;
    virtual int   disconnect (PortHandle, const std::string&) = 0;
    virtual int   disconnect_all (PortHandle) = 0;

    virtual int   connect (const std::string& src, const std::string& dst) = 0;
    virtual int   disconnect (const std::string& src, const std::string& dst) = 0;
    
    /* MIDI */

    virtual void     midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
    virtual int      midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
    virtual uint32_t get_midi_event_count (void* port_buffer);
    virtual void     midi_clear (void* port_buffer);

    /* Monitoring */

    virtual bool  can_monitor_input() const = 0;
    virtual int   request_input_monitoring (PortHandle, bool) = 0;
    virtual int   ensure_input_monitoring (PortHandle, bool) = 0;
    virtual bool  monitoring_input (PortHandle) = 0;

    /* Latency management
     */
    
    virtual void          set_latency_range (PortHandle, bool for_playback, LatencyRange) = 0;
    virtual LatencyRange  get_latency_range (PortHandle, bool for_playback) = 0;
    virtual LatencyRange  get_connected_latency_range (PortHandle, int dir) = 0;

    virtual void* get_buffer (PortHandle, pframes_t) = 0;

    virtual pframes_t last_frame_time () const = 0;
};

}

#endif /* __libardour_port_engine_h__ */