Merge branch 'master' into develop
[jack2.git] / common / JackProxyDriver.h
blob895f7643ede6dd46c25ec09eb314d4358b72765a
1 /*
2 Copyright (C) 2014 Cédric Schieli
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #ifndef __JackProxyDriver__
21 #define __JackProxyDriver__
23 #include "JackTimedDriver.h"
25 #define DEFAULT_UPSTREAM "default" /*!< Default upstream Jack server to connect to */
26 #define DEFAULT_CLIENT_NAME "proxy" /*!< Default client name to use when connecting to upstream Jack server */
28 #ifdef __APPLE__
29 #define JACK_PROXY_CLIENT_LIB "libjack.0.dylib"
30 #elif defined(WIN32)
31 #ifdef _WIN64
32 #define JACK_PROXY_CLIENT_LIB "libjack64.dll"
33 #else
34 #define JACK_PROXY_CLIENT_LIB "libjack.dll"
35 #endif
36 #else
37 #define JACK_PROXY_CLIENT_LIB "libjack.so.0"
38 #endif
40 #define PROXY_DEF_SYMBOL(ret,name,...) ret (*name) (__VA_ARGS__)
41 #define PROXY_LOAD_SYMBOL(ret,name,...) name = (ret (*) (__VA_ARGS__)) GetJackProc(fHandle, #name); assert(name)
43 namespace Jack
45 /*! \Brief This class describes the Proxy Backend
47 It uses plain Jack API to connect to an upstream server. The latter is
48 either running as the same user, or is running in promiscuous mode.
50 The main use case is the multi-user, multi-session, shared workstation:
52 - a classic server with hw driver is launched system-wide at boot time, in
53 promiscuous mode, optionally restricted to the audio group
54 - in each user session, a jackdbus server is automatically started with
55 JackProxyDriver as master driver, automatically connected to the
56 system-wide one
57 - optionally, each user run PulseAudio with a pulse-jack bridge
60 class JackProxyDriver : public JackRestarterDriver
63 private:
65 char fUpstream[JACK_CLIENT_NAME_SIZE+1]; /*<! the upstream server name */
66 char fClientName[JACK_CLIENT_NAME_SIZE+1]; /*<! client name to use when connecting */
67 const char* fPromiscuous; /*<! if not null, group or gid to use for promiscuous mode */
69 //jack data
70 jack_client_t* fClient; /*<! client handle */
71 jack_port_t** fUpstreamCapturePorts; /*<! ports registered for capture in the upstream server */
72 jack_port_t** fUpstreamPlaybackPorts; /*<! ports registered for playback in the upstream server */
73 int* fUpstreamCapturePortConnected; /*<! map of capture ports connected upstream, for optimization purpose */
74 int* fUpstreamPlaybackPortConnected; /*<! map of playback ports connected upstream, for optimization purpose */
76 bool fAutoSave; /*<! whether the local connections should be saved/restored when upstream connection is restarted */
77 bool fAutoConnect; /*<! whether the upstream ports should be automatically connected to upstream physical ports */
78 bool fDetectPlaybackChannels; /*<! whether the number of playback ports registered should match the number of upstream physical playback ports */
79 bool fDetectCaptureChannels; /*<! whether the number of capture ports registered should match the number of upstream physical capture ports */
81 bool Initialize(); /*<! establish upstream connection and register the client callbacks */
83 int AllocPorts(); /*<! register local and upstream ports */
84 int FreePorts(); /*<! unregister local ports */
85 void ConnectPorts(); /*<! connect upstream ports to physical ones */
87 int CountIO(const char*, int); /*<! get the number of upstream ports of a specific type */
89 // client callbacks
90 static int process_callback(jack_nframes_t, void*);
91 static int bufsize_callback(jack_nframes_t, void*);
92 static int srate_callback(jack_nframes_t, void*);
93 static void connect_callback(jack_port_id_t, jack_port_id_t, int, void*);
94 static void shutdown_callback(void*);
96 // indirect member callbacks
97 int bufsize_callback(jack_nframes_t);
98 int srate_callback(jack_nframes_t);
99 void connect_callback(jack_port_id_t, jack_port_id_t, int);
101 JACK_HANDLE fHandle; /*<! handle to the jack client library */
103 // map needed client library symbols as members to override those from the jackserver library
104 PROXY_DEF_SYMBOL(jack_client_t*, jack_client_open, const char*, jack_options_t, jack_status_t*, ...);
105 PROXY_DEF_SYMBOL(int, jack_set_process_callback, jack_client_t*, JackProcessCallback, void*);
106 PROXY_DEF_SYMBOL(int, jack_set_buffer_size_callback, jack_client_t*, JackBufferSizeCallback, void*);
107 PROXY_DEF_SYMBOL(int, jack_set_sample_rate_callback, jack_client_t*, JackSampleRateCallback, void*);
108 PROXY_DEF_SYMBOL(int, jack_set_port_connect_callback, jack_client_t*, JackPortConnectCallback, void*);
109 PROXY_DEF_SYMBOL(void, jack_on_shutdown, jack_client_t*, JackShutdownCallback, void*);
110 PROXY_DEF_SYMBOL(jack_nframes_t, jack_get_buffer_size, jack_client_t*);
111 PROXY_DEF_SYMBOL(jack_nframes_t, jack_get_sample_rate, jack_client_t*);
112 PROXY_DEF_SYMBOL(int, jack_activate, jack_client_t*);
113 PROXY_DEF_SYMBOL(int, jack_deactivate, jack_client_t*);
114 PROXY_DEF_SYMBOL(jack_port_t*, jack_port_by_id, jack_client_t*, jack_port_id_t);
115 PROXY_DEF_SYMBOL(int, jack_port_is_mine, const jack_client_t*, const jack_port_t*);
116 PROXY_DEF_SYMBOL(const char**, jack_get_ports, jack_client_t*, const char*, const char*, unsigned long);
117 PROXY_DEF_SYMBOL(void, jack_free, void*);
118 PROXY_DEF_SYMBOL(jack_port_t*, jack_port_register, jack_client_t*, const char*, const char*, unsigned long, unsigned long);
119 PROXY_DEF_SYMBOL(int, jack_port_unregister, jack_client_t*, jack_port_t*);
120 PROXY_DEF_SYMBOL(void*, jack_port_get_buffer, jack_port_t*, jack_nframes_t);
121 PROXY_DEF_SYMBOL(int, jack_connect, jack_client_t*, const char*, const char*);
122 PROXY_DEF_SYMBOL(const char*, jack_port_name, const jack_port_t*);
123 PROXY_DEF_SYMBOL(int, jack_client_close, jack_client_t*);
125 /*! load the needed library symbols */
126 void LoadSymbols()
128 PROXY_LOAD_SYMBOL(jack_client_t*, jack_client_open, const char*, jack_options_t, jack_status_t*, ...);
129 PROXY_LOAD_SYMBOL(int, jack_set_process_callback, jack_client_t*, JackProcessCallback, void*);
130 PROXY_LOAD_SYMBOL(int, jack_set_buffer_size_callback, jack_client_t*, JackBufferSizeCallback, void*);
131 PROXY_LOAD_SYMBOL(int, jack_set_sample_rate_callback, jack_client_t*, JackSampleRateCallback, void*);
132 PROXY_LOAD_SYMBOL(int, jack_set_port_connect_callback, jack_client_t*, JackPortConnectCallback, void*);
133 PROXY_LOAD_SYMBOL(void, jack_on_shutdown, jack_client_t*, JackShutdownCallback, void*);
134 PROXY_LOAD_SYMBOL(jack_nframes_t, jack_get_buffer_size, jack_client_t*);
135 PROXY_LOAD_SYMBOL(jack_nframes_t, jack_get_sample_rate, jack_client_t*);
136 PROXY_LOAD_SYMBOL(int, jack_activate, jack_client_t*);
137 PROXY_LOAD_SYMBOL(int, jack_deactivate, jack_client_t*);
138 PROXY_LOAD_SYMBOL(jack_port_t*, jack_port_by_id, jack_client_t*, jack_port_id_t);
139 PROXY_LOAD_SYMBOL(int, jack_port_is_mine, const jack_client_t*, const jack_port_t*);
140 PROXY_LOAD_SYMBOL(const char**, jack_get_ports, jack_client_t*, const char*, const char*, unsigned long);
141 PROXY_LOAD_SYMBOL(void, jack_free, void*);
142 PROXY_LOAD_SYMBOL(jack_port_t*, jack_port_register, jack_client_t*, const char*, const char*, unsigned long, unsigned long);
143 PROXY_LOAD_SYMBOL(int, jack_port_unregister, jack_client_t*, jack_port_t*);
144 PROXY_LOAD_SYMBOL(void*, jack_port_get_buffer, jack_port_t*, jack_nframes_t);
145 PROXY_LOAD_SYMBOL(int, jack_connect, jack_client_t*, const char*, const char*);
146 PROXY_LOAD_SYMBOL(const char*, jack_port_name, const jack_port_t*);
147 PROXY_LOAD_SYMBOL(int, jack_client_close, jack_client_t*);
149 int LoadClientLib(); /*!< load the client library */
151 public:
153 JackProxyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
154 const char* upstream, const char* promiscuous, char* client_name, bool auto_connect, bool auto_save);
155 virtual ~JackProxyDriver();
157 int Open(jack_nframes_t buffer_size,
158 jack_nframes_t samplerate,
159 bool capturing,
160 bool playing,
161 int inchannels,
162 int outchannels,
163 bool monitor,
164 const char* capture_driver_name,
165 const char* playback_driver_name,
166 jack_nframes_t capture_latency,
167 jack_nframes_t playback_latency);
168 int Close();
170 int Stop();
172 int Attach();
173 int Detach();
175 int Read();
176 int Write();
181 #endif