Mercurial > hg > piper-cpp
comparison vamp-client/CapnpRRClient.h @ 118:ff3fd8d1b2dc
Boilerplate comments
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 27 Oct 2016 12:01:37 +0100 |
parents | d74dfc11927c |
children | 2004ec2b653e |
comparison
equal
deleted
inserted
replaced
117:5dffc5147176 | 118:ff3fd8d1b2dc |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
2 /* | |
3 Piper C++ | |
4 | |
5 An API for audio analysis and feature extraction plugins. | |
6 | |
7 Centre for Digital Music, Queen Mary, University of London. | |
8 Copyright 2006-2016 Chris Cannam and QMUL. | |
9 | |
10 Permission is hereby granted, free of charge, to any person | |
11 obtaining a copy of this software and associated documentation | |
12 files (the "Software"), to deal in the Software without | |
13 restriction, including without limitation the rights to use, copy, | |
14 modify, merge, publish, distribute, sublicense, and/or sell copies | |
15 of the Software, and to permit persons to whom the Software is | |
16 furnished to do so, subject to the following conditions: | |
17 | |
18 The above copyright notice and this permission notice shall be | |
19 included in all copies or substantial portions of the Software. | |
20 | |
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | |
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
26 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
28 | |
29 Except as contained in this notice, the names of the Centre for | |
30 Digital Music; Queen Mary, University of London; and Chris Cannam | |
31 shall not be used in advertising or otherwise to promote the sale, | |
32 use or other dealings in this Software without prior written | |
33 authorization. | |
34 */ | |
2 | 35 |
3 #ifndef PIPER_CAPNP_CLIENT_H | 36 #ifndef PIPER_CAPNP_CLIENT_H |
4 #define PIPER_CAPNP_CLIENT_H | 37 #define PIPER_CAPNP_CLIENT_H |
5 | 38 |
6 #include "Loader.h" | 39 #include "Loader.h" |
23 * such as a subprocess pipe arrangement. Only one request can be | 56 * such as a subprocess pipe arrangement. Only one request can be |
24 * handled at a time. This class is thread-safe if and only if it is | 57 * handled at a time. This class is thread-safe if and only if it is |
25 * constructed with a thread-safe SynchronousTransport implementation. | 58 * constructed with a thread-safe SynchronousTransport implementation. |
26 */ | 59 */ |
27 class CapnpRRClient : public PluginClient, | 60 class CapnpRRClient : public PluginClient, |
28 public Loader | 61 public Loader |
29 { | 62 { |
30 // unsigned to avoid undefined behaviour on possible wrap | 63 // unsigned to avoid undefined behaviour on possible wrap |
31 typedef uint32_t ReqId; | 64 typedef uint32_t ReqId; |
32 | 65 |
33 class CompletenessChecker : public MessageCompletenessChecker { | 66 class CompletenessChecker : public MessageCompletenessChecker { |
71 if (!m_transport->isOK()) { | 104 if (!m_transport->isOK()) { |
72 throw std::runtime_error("Piper server failed to start"); | 105 throw std::runtime_error("Piper server failed to start"); |
73 } | 106 } |
74 | 107 |
75 capnp::MallocMessageBuilder message; | 108 capnp::MallocMessageBuilder message; |
76 piper::RpcRequest::Builder builder = message.initRoot<piper::RpcRequest>(); | 109 piper::RpcRequest::Builder builder = message.initRoot<piper::RpcRequest>(); |
77 VampnProto::buildRpcRequest_List(builder); | 110 VampnProto::buildRpcRequest_List(builder); |
78 ReqId id = getId(); | 111 ReqId id = getId(); |
79 builder.getId().setNumber(id); | 112 builder.getId().setNumber(id); |
80 | 113 |
81 auto karr = call(message); | 114 auto karr = call(message); |
82 | 115 |
83 capnp::FlatArrayMessageReader responseMessage(karr); | 116 capnp::FlatArrayMessageReader responseMessage(karr); |
84 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); | 117 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); |
85 | 118 |
86 checkResponseType(reader, piper::RpcResponse::Response::Which::LIST, id); | 119 checkResponseType(reader, piper::RpcResponse::Response::Which::LIST, id); |
137 | 170 |
138 VampnProto::buildRpcRequest_Configure(builder, request, m_mapper); | 171 VampnProto::buildRpcRequest_Configure(builder, request, m_mapper); |
139 ReqId id = getId(); | 172 ReqId id = getId(); |
140 builder.getId().setNumber(id); | 173 builder.getId().setNumber(id); |
141 | 174 |
142 auto karr = call(message); | 175 auto karr = call(message); |
143 | 176 |
144 capnp::FlatArrayMessageReader responseMessage(karr); | 177 capnp::FlatArrayMessageReader responseMessage(karr); |
145 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); | 178 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); |
146 | 179 |
147 //!!! handle (explicit) error case | 180 //!!! handle (explicit) error case |
172 request.timestamp = timestamp; | 205 request.timestamp = timestamp; |
173 | 206 |
174 capnp::MallocMessageBuilder message; | 207 capnp::MallocMessageBuilder message; |
175 piper::RpcRequest::Builder builder = message.initRoot<piper::RpcRequest>(); | 208 piper::RpcRequest::Builder builder = message.initRoot<piper::RpcRequest>(); |
176 VampnProto::buildRpcRequest_Process(builder, request, m_mapper); | 209 VampnProto::buildRpcRequest_Process(builder, request, m_mapper); |
177 ReqId id = getId(); | 210 ReqId id = getId(); |
178 builder.getId().setNumber(id); | 211 builder.getId().setNumber(id); |
179 | 212 |
180 auto karr = call(message); | 213 auto karr = call(message); |
181 | 214 |
182 capnp::FlatArrayMessageReader responseMessage(karr); | 215 capnp::FlatArrayMessageReader responseMessage(karr); |
183 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); | 216 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); |
184 | 217 |
185 //!!! handle (explicit) error case | 218 //!!! handle (explicit) error case |
209 | 242 |
210 VampnProto::buildRpcRequest_Finish(builder, request, m_mapper); | 243 VampnProto::buildRpcRequest_Finish(builder, request, m_mapper); |
211 ReqId id = getId(); | 244 ReqId id = getId(); |
212 builder.getId().setNumber(id); | 245 builder.getId().setNumber(id); |
213 | 246 |
214 auto karr = call(message); | 247 auto karr = call(message); |
215 | 248 |
216 capnp::FlatArrayMessageReader responseMessage(karr); | 249 capnp::FlatArrayMessageReader responseMessage(karr); |
217 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); | 250 piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>(); |
218 | 251 |
219 //!!! handle (explicit) error case | 252 //!!! handle (explicit) error case |
225 reader.getResponse().getFinish(), | 258 reader.getResponse().getFinish(), |
226 m_mapper); | 259 m_mapper); |
227 | 260 |
228 m_mapper.removePlugin(m_mapper.pluginToHandle(plugin)); | 261 m_mapper.removePlugin(m_mapper.pluginToHandle(plugin)); |
229 | 262 |
230 // Don't delete the plugin. It's the plugin that is supposed | 263 // Don't delete the plugin. It's the plugin that is supposed |
231 // to be calling us here | 264 // to be calling us here |
232 | 265 |
233 return pr.features; | 266 return pr.features; |
234 } | 267 } |
235 | 268 |
236 virtual void | 269 virtual void |
269 } | 302 } |
270 | 303 |
271 static | 304 static |
272 kj::Array<capnp::word> | 305 kj::Array<capnp::word> |
273 toKJArray(const std::vector<char> &buffer) { | 306 toKJArray(const std::vector<char> &buffer) { |
274 // We could do this whole thing with fewer copies, but let's | 307 // We could do this whole thing with fewer copies, but let's |
275 // see whether it matters first | 308 // see whether it matters first |
276 size_t wordSize = sizeof(capnp::word); | 309 size_t wordSize = sizeof(capnp::word); |
277 size_t words = buffer.size() / wordSize; | 310 size_t words = buffer.size() / wordSize; |
278 kj::Array<capnp::word> karr(kj::heapArray<capnp::word>(words)); | 311 kj::Array<capnp::word> karr(kj::heapArray<capnp::word>(words)); |
279 memcpy(karr.begin(), buffer.data(), words * wordSize); | 312 memcpy(karr.begin(), buffer.data(), words * wordSize); |
280 return karr; | 313 return karr; |
281 } | 314 } |
282 | 315 |
283 void | 316 void |
284 checkResponseType(const piper::RpcResponse::Reader &r, | 317 checkResponseType(const piper::RpcResponse::Reader &r, |
285 piper::RpcResponse::Response::Which type, | 318 piper::RpcResponse::Response::Which type, |
286 ReqId id) { | 319 ReqId id) { |
287 | 320 |
288 if (r.getResponse().which() != type) { | 321 if (r.getResponse().which() != type) { |
289 std::cerr << "checkResponseType: wrong response type (received " | 322 std::cerr << "checkResponseType: wrong response type (received " |
290 << int(r.getResponse().which()) << ", expected " | 323 << int(r.getResponse().which()) << ", expected " |
291 << int(type) << ")" | 324 << int(type) << ")" |
292 << std::endl; | 325 << std::endl; |
293 throw std::runtime_error("Wrong response type"); | 326 throw std::runtime_error("Wrong response type"); |
294 } | 327 } |
295 if (ReqId(r.getId().getNumber()) != id) { | 328 if (ReqId(r.getId().getNumber()) != id) { |
296 std::cerr << "checkResponseType: wrong response id (received " | 329 std::cerr << "checkResponseType: wrong response id (received " |
297 << r.getId().getNumber() << ", expected " << id << ")" | 330 << r.getId().getNumber() << ", expected " << id << ")" |
298 << std::endl; | 331 << std::endl; |
299 throw std::runtime_error("Wrong response id"); | 332 throw std::runtime_error("Wrong response id"); |
300 } | 333 } |
301 } | 334 } |
302 | 335 |
303 kj::Array<capnp::word> | 336 kj::Array<capnp::word> |
304 call(capnp::MallocMessageBuilder &message) { | 337 call(capnp::MallocMessageBuilder &message) { |
305 auto arr = capnp::messageToFlatArray(message); | 338 auto arr = capnp::messageToFlatArray(message); |
306 auto responseBuffer = m_transport->call(arr.asChars().begin(), | 339 auto responseBuffer = m_transport->call(arr.asChars().begin(), |
307 arr.asChars().size()); | 340 arr.asChars().size()); |
308 return toKJArray(responseBuffer); | 341 return toKJArray(responseBuffer); |
309 } | 342 } |
310 | 343 |
311 PluginHandleMapper::Handle | 344 PluginHandleMapper::Handle |
312 serverLoad(std::string key, float inputSampleRate, int adapterFlags, | 345 serverLoad(std::string key, float inputSampleRate, int adapterFlags, |
313 PluginStaticData &psd, | 346 PluginStaticData &psd, |
323 | 356 |
324 VampnProto::buildRpcRequest_Load(builder, request); | 357 VampnProto::buildRpcRequest_Load(builder, request); |
325 ReqId id = getId(); | 358 ReqId id = getId(); |
326 builder.getId().setNumber(id); | 359 builder.getId().setNumber(id); |
327 | 360 |
328 auto karr = call(message); | 361 auto karr = call(message); |
329 | 362 |
330 //!!! ... --> will also need some way to kill this process | 363 //!!! ... --> will also need some way to kill this process |
331 //!!! (from another thread) | 364 //!!! (from another thread) |
332 | 365 |
333 capnp::FlatArrayMessageReader responseMessage(karr); | 366 capnp::FlatArrayMessageReader responseMessage(karr); |