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);