Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
server.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "server.hh"
3#include "jsonipc/jsonipc.hh"
4#include "crawler.hh"
5#include "platform.hh"
6#include "properties.hh"
7#include "serialize.hh"
8#include "main.hh"
9#include "driver.hh"
10#include "utils.hh"
11#include "project.hh"
12#include "path.hh"
13#include "clapdevice.hh"
14#include "sndfile.hh"
15#include "wave.hh"
16#include "internal.hh"
17#include <atomic>
18
19namespace Ase {
20
21// == ServerImpl ==
22static constexpr size_t telemetry_size = 4 * 1024 * 1024;
23
24ServerImpl *SERVER = nullptr;
25
26ServerImpl::ServerImpl () :
27 telemetry_arena (telemetry_size)
28{
29 assert_return (telemetry_arena.reserved() >= telemetry_size);
30 Block telemetry_header = telemetry_arena.allocate (64);
31 assert_return (telemetry_arena.location() == uint64 (telemetry_header.block_start));
32 const uint8_t header_sentinel[64] = {
33 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
34 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
35 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b,
36 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f,
37 };
38 assert_return (telemetry_header.block_length == sizeof (header_sentinel));
39 memcpy (telemetry_header.block_start, header_sentinel, telemetry_header.block_length);
40 if (!SERVER)
41 SERVER = this;
42}
43
44ServerImpl::~ServerImpl ()
45{
46 fatal_error ("ServerImpl references must persist");
47 if (SERVER == this)
48 SERVER = nullptr;
49}
50
52ServerImpl::get_version ()
53{
54 return ase_version();
55}
56
58ServerImpl::get_build_id ()
59{
60 return ase_build_id();
61}
62
64ServerImpl::get_opus_version ()
65{
66 return wave_writer_opus_version();
67}
68
70ServerImpl::get_flac_version ()
71{
72 return wave_writer_flac_version();
73}
74
76ServerImpl::get_clap_version()
77{
78 return ClapDeviceImpl::clap_version();
79}
80
82ServerImpl::get_sndfile_version ()
83{
84 return libsndfile_version();
85}
86
87void
88ServerImpl::shutdown ()
89{
90 // defer quit() slightly, so remote calls are still completed
91 main_loop->exec_timer ([] () { main_loop->quit (0); }, 5, -1, EventLoop::PRIORITY_NORMAL);
92}
93
94ProjectP
95ServerImpl::last_project ()
96{
97 return Project::last_project();
98}
99
100ProjectP
101ServerImpl::create_project (String projectname)
102{
103 return ProjectImpl::create (projectname);
104}
105
107ServerImpl::list_preferences ()
108{
109 const CStringS list = Preference::list();
110 return { std::begin (list), std::end (list) };
111}
112
113PropertyP
114ServerImpl::access_preference (const String &ident)
115{
116 return Preference::find (ident);
117}
118
119ServerImplP
120ServerImpl::instancep ()
121{
122 static ServerImplP *sptr = new ServerImplP (std::make_shared<ServerImpl>());
123 return *sptr;
124}
125
126bool
127ServerImpl::set_data (const String &key, const Value &value)
128{
129 const String ckey = canonify_key (key);
130 if (ckey.size() && ckey[0] != '_')
131 {
132 const String filename = Path::join (Path::xdg_dir ("CONFIG"), "anklang", ckey);
133 emit_event ("data", key);
134 return Path::stringwrite (filename, value.as_string());
135 }
136 else
137 return GadgetImpl::set_data (ckey, value);
138}
139
140Value
141ServerImpl::get_data (const String &key) const
142{
143 const String ckey = canonify_key (key);
144 if (ckey.size() && ckey[0] != '_')
145 {
146 const String filename = Path::join (Path::xdg_dir ("CONFIG"), "anklang", ckey);
147 return Path::stringread (filename);
148 }
149 else
150 return GadgetImpl::get_data (ckey);
151}
152
153// == Server ==
154ServerP
155Server::instancep ()
156{
157 return ServerImpl::instancep();
158}
159
160Server&
161Server::instance ()
162{
163 return *instancep();
164}
165
166// == FileCrawler ==
167ResourceCrawlerP
168Server::dir_crawler (const String &cwd)
169{
170 return FileCrawler::make_shared (cwd, true, false);
171}
172
173ResourceCrawlerP
174Server::url_crawler (const String &url)
175{
176 if (App.web_socket_server) {
177 String dir = App.web_socket_server->map_url (url);
178 if (!dir.empty())
179 return FileCrawler::make_shared (dir, false, false);
180 }
181 return nullptr;
182}
183
184String
185Server::engine_stats ()
186{
187 const String s = App.engine->engine_stats (0);
188 printerr ("Server::engine_stats:\n%s\n", s);
189 return s;
190}
191
192void
193Server::exit_program (int status)
194{
195 main_loop->quit (status);
196}
197
198// == Choice ==
199Choice::Choice (String ident_, String label_, String blurb_, String notice_, String warning_) :
200 ident (ident_.empty() ? string_to_identifier (label_) : ident_),
201 label (label_), blurb (blurb_), notice (notice_), warning (warning_)
202{
203 assert_return (ident.empty() == false);
204}
205
206Choice::Choice (String ident_, IconString icon_, String label_, String blurb_, String notice_, String warning_) :
207 ident (ident_.empty() ? string_to_identifier (label_) : ident_),
208 icon (icon_), label (label_), blurb (blurb_), notice (notice_), warning (warning_)
209{
210 assert_return (ident.empty() == false);
211}
212
213Choice::Choice (IconString icon_, String label_, String blurb_) :
214 Choice ("", icon_, label_, blurb_)
215{}
216
217ChoiceS&
218operator+= (ChoiceS &choices, Choice &&newchoice)
219{
220 choices.push_back (std::move (newchoice));
221 return choices;
222}
223
224// == Error ==
226const char*
228{
229 switch (error)
230 {
231 // errno aliases are left to strerror
232 case Error::NONE: return _("OK");
233 // Ase specific errors
234 case Error::INTERNAL: return _("Internal error (please report)");
235 // file errors
236 case Error::FILE_EOF: return _("End of file");
237 case Error::FILE_OPEN_FAILED: return _("Open failed");
238 case Error::FILE_SEEK_FAILED: return _("Seek failed");
239 case Error::FILE_READ_FAILED: return _("Read failed");
240 case Error::FILE_WRITE_FAILED: return _("Write failed");
241 // content errors
242 case Error::PARSE_ERROR: return _("Parsing error");
243 case Error::NO_HEADER: return _("Failed to detect header");
244 case Error::NO_SEEK_INFO: return _("Failed to retrieve seek information");
245 case Error::NO_DATA_AVAILABLE: return _("No data available");
246 case Error::DATA_CORRUPT: return _("Data corrupt");
247 case Error::WRONG_N_CHANNELS: return _("Wrong number of channels");
248 case Error::FORMAT_INVALID: return _("Invalid format");
249 case Error::FORMAT_UNKNOWN: return _("Unknown format");
250 case Error::DATA_UNMATCHED: return _("Requested data values unmatched");
251 case Error::CODEC_FAILURE: return _("Codec failure");
252 case Error::BROKEN_ARCHIVE: return _("Broken archive");
253 case Error::BAD_PROJECT: return _("Not a valid project");
254 case Error::NO_PROJECT_DIR: return _("Missing project directory");
255 // Device errors
256 case Error::DEVICE_NOT_AVAILABLE: return _("No device (driver) available");
257 case Error::DEVICE_ASYNC: return _("Device not async capable");
258 case Error::DEVICE_BUSY: return _("Device busy");
259 case Error::DEVICE_FORMAT: return _("Failed to configure device format");
260 case Error::DEVICE_BUFFER: return _("Failed to configure device buffer");
261 case Error::DEVICE_LATENCY: return _("Failed to configure device latency");
262 case Error::DEVICE_CHANNELS: return _("Failed to configure number of device channels");
263 case Error::DEVICE_FREQUENCY: return _("Failed to configure device frequency");
264 case Error::DEVICES_MISMATCH: return _("Device configurations mismatch");
265 // miscellaneous errors
266 case Error::WAVE_NOT_FOUND: return _("No such wave");
267 case Error::UNIMPLEMENTED: return _("Functionality not implemented");
268 case Error::INVALID_PROPERTY: return _("Invalid object property");
269 case Error::INVALID_MIDI_CONTROL: return _("Invalid MIDI control type");
270 case Error::OPERATION_BUSY: return _("Operation already in prgress");
271 default:
272 return strerror (int (error));
273 }
274}
275
276// Map errno onto Ase::Error.
277Error
278ase_error_from_errno (int sys_errno, Error fallback)
279{
280 if (sys_errno < int (Error::INTERNAL))
281 return Error (sys_errno); // Error includes errnos
282 else
283 return fallback;
284}
285
286String
287ServerImpl::error_blurb (Error error) const
288{
289 return ase_error_blurb (error);
290}
291
292// == MusicalTuning ==
293static EnumInfo
294musical_tuning_info (MusicalTuning musicaltuning)
295{
296 switch (musicaltuning)
297 {
298 // Equal Temperament: http://en.wikipedia.org/wiki/Equal_temperament
299 case MusicalTuning::OD_12_TET:
300 return { _("12 Tone Equal Temperament"), // http://en.wikipedia.org/wiki/Equal_temperament
301 _("The most common tuning system for modern Western music, "
302 "is the twelve-tone equal temperament, abbreviated as 12-TET, "
303 "which divides the octave into 12 equal parts.") };
304 case MusicalTuning::OD_7_TET:
305 return { _("7 Tone Equal Temperament"), // http://en.wikipedia.org/wiki/Equal_temperament
306 _("A fairly common tuning system is the seven-tone equal temperament tuning system, "
307 "abbreviated as 7-TET. It divides the octave into 7 equal parts using 171 cent steps.") };
308 case MusicalTuning::OD_5_TET:
309 return { _("5 Tone Equal Temperament"), // http://en.wikipedia.org/wiki/Equal_temperament
310 _("A fairly common tuning system is the five-tone equal temperament tuning system, "
311 "abbreviated as 5-TET. It divides the octave into 5 equal parts using 240 cent steps.") };
312 // Rational Intonation: http://en.wikipedia.org/wiki/Just_intonation
313 case MusicalTuning::DIATONIC_SCALE:
314 return { _("Diatonic Scale"), // http://en.wikipedia.org/wiki/Diatonic_scale
315 _("In music theory, a diatonic scale (also: heptatonia prima) is a seven-note "
316 "musical scale comprising five whole-tone and two half-tone steps. "
317 "The half tones are maximally separated, so between two half-tone steps "
318 "there are either two or three whole tones, repeating per octave.") }; // Werckmeister I
319 case MusicalTuning::INDIAN_SCALE:
320 return { _("Indian Scale"), // http://en.wikipedia.org/wiki/Just_intonation#Indian_scales
321 _("Diatonic scale used in Indian music with wolf interval at Dha, close to 3/2") };
322 case MusicalTuning::PYTHAGOREAN_TUNING:
323 return { _("Pythagorean Tuning"), // http://en.wikipedia.org/wiki/Pythagorean_tuning
324 _("Pythagorean tuning is the oldest way of tuning the 12-note chromatic scale, "
325 "in which the frequency relationships of all intervals are based on the ratio 3:2. "
326 "Its discovery is generally credited to Pythagoras.") };
327 case MusicalTuning::PENTATONIC_5_LIMIT:
328 return { _("Pentatonic 5-limit"), // http://en.wikipedia.org/wiki/Pentatonic_scale
329 _("Pentatonic scales are used in modern jazz and pop/rock contexts "
330 "because they work exceedingly well over several chords diatonic "
331 "to the same key, often better than the parent scale.") };
332 case MusicalTuning::PENTATONIC_BLUES:
333 return { _("Pentatonic Blues"), // http://en.wikipedia.org/wiki/Pentatonic_scale
334 _("The blues scale is the minor pentatonic with an additional augmented fourth, "
335 "which is referred to as the \"blues note\".") };
336 case MusicalTuning::PENTATONIC_GOGO:
337 return { _("Pentatonic Gogo"), // http://en.wikipedia.org/wiki/Pentatonic_scale
338 _("The Pentatonic Gogo scale is an anhemitonic pentatonic scale used to tune the "
339 "instruments of the Gogo people of Tanzania.") };
340 // Meantone Temperament: http://en.wikipedia.org/wiki/Meantone_temperament
341 case MusicalTuning::QUARTER_COMMA_MEANTONE:
342 return { _("Quarter-Comma Meantone"), // http://en.wikipedia.org/wiki/Quarter-comma_meantone
343 _("Quarter-comma meantone was the most common meantone temperament in the "
344 "sixteenth and seventeenth centuries and sometimes used later.") }; // Werckmeister II
345 case MusicalTuning::SILBERMANN_SORGE:
346 return { _("Silbermann-Sorge Temperament"), // http://de.wikipedia.org/wiki/Silbermann-Sorge-Temperatur
347 _("The Silbermann-Sorge temperament is a meantone temperament used for "
348 "Baroque era organs by Gottfried Silbermann.") };
349 // Well Temperament: http://en.wikipedia.org/wiki/Well_temperament
350 case MusicalTuning::WERCKMEISTER_3:
351 return { _("Werckmeister III"), // http://en.wikipedia.org/wiki/Werckmeister_temperament
352 _("This tuning uses mostly pure (perfect) fifths, as in Pythagorean tuning, but each "
353 "of the fifths C-G, G-D, D-A and B-F# is made smaller, i.e. tempered by 1/4 comma. "
354 "Werckmeister designated this tuning as particularly suited for playing chromatic music.") };
355 case MusicalTuning::WERCKMEISTER_4:
356 return { _("Werckmeister IV"), // http://en.wikipedia.org/wiki/Werckmeister_temperament
357 _("In this tuning the fifths C-G, D-A, E-B, F#-C#, and Bb-F are tempered narrow by 1/3 comma, "
358 "and the fifths G#-D# and Eb-Bb are widened by 1/3 comma. The other fifths are pure. "
359 "Most of its intervals are close to sixth-comma meantone. "
360 "Werckmeister designed this tuning for playing mainly diatonic music.") };
361 case MusicalTuning::WERCKMEISTER_5:
362 return { _("Werckmeister V"), // http://en.wikipedia.org/wiki/Werckmeister_temperament
363 _("In this tuning the fifths D-A, A-E, F#-C#, C#-G#, and F-C are narrowed by 1/4 comma, "
364 "and the fifth G#-D# is widened by 1/4 comma. The other fifths are pure. "
365 "This temperament is closer to equal temperament than Werckmeister III or IV.") };
366 case MusicalTuning::WERCKMEISTER_6:
367 return { _("Werckmeister VI"), // http://en.wikipedia.org/wiki/Werckmeister_temperament
368 _("This tuning is also known as Septenarius tuning is based on a division of the monochord "
369 "length into 196 = 7 * 7 * 4 parts. "
370 "The resulting scale has rational frequency relationships, but in practice involves pure "
371 "and impure sounding fifths. "
372 "Werckmeister described the Septenarius as a \"temperament which has nothing at all to do "
373 "with the divisions of the comma, nevertheless in practice so correct that one can be really "
374 "satisfied with it\".") };
375 case MusicalTuning::KIRNBERGER_3:
376 return { _("Kirnberger III"), // http://en.wikipedia.org/wiki/Johann_Philipp_Kirnberger_temperament
377 _("Kirnberger's method of compensating for and closing the circle of fifths is to split the \"wolf\" "
378 "interval known to those who have used meantone temperaments between four fifths instead, "
379 "allowing for four 1/4-comma wolves to take their place. "
380 "1/4-comma wolves are used extensively in meantone and are much easier to tune and to listen to. "
381 "Therefore, only one third remains pure (between C and E).") };
382 case MusicalTuning::YOUNG:
383 return { _("Young Temperament"), // http://en.wikipedia.org/wiki/Young_temperament
384 _("Thomas Young devised a form of musical tuning to make the harmony most perfect in those keys which "
385 "are the most frequently used (give better major thirds in those keys), but to not have any unplayable keys. "
386 "This is attempted by tuning upwards from C a sequence of six pure fourths, "
387 "as well as six equally imperfect fifths.") };
388 default:
389 return { "", "" };
390 }
391}
392static bool musical_tuning_info__ = EnumInfo::impl (musical_tuning_info);
393
394String
395ServerImpl::musical_tuning_blurb (MusicalTuning musicaltuning) const
396{
397 return EnumInfo::value_info (musicaltuning).blurb;
398}
399
400String
401ServerImpl::musical_tuning_label (MusicalTuning musicaltuning) const
402{
403 return EnumInfo::value_info (musicaltuning).label;
404}
405
406static std::atomic<uint> user_note_id = 1;
407
408uint64
409ServerImpl::user_note (const String &text, const String &channel, UserNote::Flags flags, const String &rest)
410{
411 UserNote unote { user_note_id++, flags, channel.empty() ? "misc" : channel, text, rest };
412 ValueR vrec;
413 json_parse (json_stringify (unote), vrec);
414 this->emit_event ("usernote", "", vrec);
415 String s;
416 s += string_format ("%s: usernote[%04x]: %s: %s", program_alias(), unote.noteid, unote.channel, unote.text);
417 if (!unote.rest.empty())
418 s += " (" + unote.rest + ")";
419 printerr ("%s\n", string_replace (s, "\n", "\t"));
420 return unote.noteid;
421}
422
423bool
424ServerImpl::user_reply (uint64 noteid, uint r)
425{
426 return false; // unhandled
427}
428
429ServerImpl::Block
430ServerImpl::telemem_allocate (uint32 length) const
431{
432 return telemetry_arena.allocate (length);
433}
434
435void
436ServerImpl::telemem_release (Block telememblock) const
437{
438 telemetry_arena.release (telememblock);
439}
440
441ptrdiff_t
442ServerImpl::telemem_start () const
443{
444 return telemetry_arena.location();
445}
446
447static bool
448validate_telemetry_segments (const TelemetrySegmentS &segments, size_t *payloadlength)
449{
450 *payloadlength = 0;
451 const TelemetrySegment *last = nullptr;
452 for (const auto &seg : segments)
453 {
454 if (last && seg.offset < last->offset + last->length)
455 return false; // check sorting and non-overlapping
456 if (seg.offset < 0 || (seg.offset & 3) || seg.length <= 0 || (seg.length & 3) ||
457 size_t (seg.offset + seg.length) > telemetry_size)
458 return false;
459 *payloadlength += seg.length;
460 last = &seg;
461 }
462 return true;
463}
464
465ASE_CLASS_DECLS (TelemetryPlan);
467public:
468 int32 interval_ms_ = -1;
469 uint timerid_ = 0;
470 JsonapiBinarySender send_blob_;
471 TelemetrySegmentS segments_;
472 const char *telemem_ = nullptr;
473 String payload_;
474 void send_telemetry();
475 void setup (const char *start, size_t payloadlength, const TelemetrySegmentS &plan, int32 interval_ms);
477};
478static CustomDataKey<TelemetryPlanP> telemetry_key;
479
480bool
481ServerImpl::broadcast_telemetry (const TelemetrySegmentS &segments, int32 interval_ms)
482{
483 size_t payloadlength = 0;
484 if (!validate_telemetry_segments (segments, &payloadlength))
485 {
486 warning ("%s: invalid segment list", "Ase::ServerImpl::broadcast_telemetry");
487 return false;
488 }
489 CustomDataContainer *cdata = jsonapi_connection_data();
490 if (!cdata)
491 {
492 warning ("%s: cannot broadcast telemetry without jsonapi connection", "Ase::ServerImpl::broadcast_telemetry");
493 return false;
494 }
495 TelemetryPlanP tplan = cdata->get_custom_data (&telemetry_key);
496 if (!tplan)
497 {
499 cdata->set_custom_data (&telemetry_key, tplan);
500 tplan->send_blob_ = jsonapi_connection_sender();
501 }
502 tplan->setup ((const char*) telemetry_arena.location(), payloadlength, segments, interval_ms);
503 return true;
504}
505
506void
507TelemetryPlan::setup (const char *start, size_t payloadlength, const TelemetrySegmentS &segments, int32 interval_ms)
508{
509 if (timerid_ == 0 || interval_ms_ != interval_ms)
510 {
511 if (timerid_)
512 main_loop->remove (timerid_);
513 auto send_telemetry = [this] () { this->send_telemetry(); return true; };
514 interval_ms_ = interval_ms;
515 timerid_ = interval_ms <= 0 || segments.empty() ? 0 : main_loop->exec_timer (send_telemetry, interval_ms, interval_ms);
516 }
517 if (timerid_)
518 {
519 telemem_ = start;
520 segments_ = segments;
521 payload_.resize (payloadlength);
522 }
523 else
524 {
525 telemem_ = nullptr;
526 segments_ = {};
527 payload_.clear();
528 }
529}
530
531void
532TelemetryPlan::send_telemetry ()
533{
534 char *data = &payload_[0];
535 size_t datapos = 0;
536 for (const auto &seg : segments_) // offsets and lengths were validated earlier
537 {
538 memcpy (data + datapos, telemem_ + seg.offset, seg.length);
539 datapos += seg.length;
540 }
541 send_blob_ (payload_);
542}
543
544TelemetryPlan::~TelemetryPlan()
545{
546 if (timerid_)
547 {
548 main_loop->remove (timerid_);
549 timerid_ = 0;
550 }
551}
552
553} // Ase
T begin(T... args)
T get_custom_data(CustomDataKey< T > *key) const
Retrieve contents of the custom keyed data member, returns DataKey::fallback if nothing was set.
Definition utils.hh:113
void set_custom_data(CustomDataKey< T > *key, T data)
Assign data to the custom keyed data member, deletes any previously set data.
Definition utils.hh:110
CustomDataKey objects are used to identify and manage custom data members of CustomDataContainer obje...
Definition utils.hh:81
bool broadcast_telemetry(const TelemetrySegmentS &plan, int32 interval_ms) override
Broadcast telemetry memory segments to the current Jsonipc connection.
Definition server.cc:481
Central singleton, serves as API entry point.
Definition api.hh:400
T clear(T... args)
T data(T... args)
T empty(T... args)
T end(T... args)
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
Definition internal.hh:29
#define _(...)
Retrieve the translation of a C or C++ string.
Definition internal.hh:18
memcpy
The Anklang C++ API namespace.
Definition api.hh:9
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
String string_to_identifier(const String &input)
Force lower case, alphanumerics + underscore and non-digit start.
Definition strings.cc:54
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:25
int32_t int32
A 32-bit signed integer.
Definition cxxaux.hh:28
bool json_parse(const String &jsonstring, T &target)
Parse a well formed JSON string and assign contents to target.
Definition serialize.hh:538
Error
Enum representing Error states.
Definition api.hh:22
const char * ase_error_blurb(Error error)
Describe Error condition.
Definition server.cc:227
String string_replace(const String &input, const String &marker, const String &replacement, size_t maxn)
Replace substring marker in input with replacement, at most maxn times.
Definition strings.cc:1144
ChoiceS & operator+=(ChoiceS &choices, Choice &&newchoice)
Convenience ChoiceS construction helper.
Definition server.cc:218
String program_alias()
Retrieve the program name as used for logging or debug messages.
Definition platform.cc:849
const char * ase_version()
Provide a string containing the package version.
Definition platform.cc:835
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35
uint32_t uint32
A 32-bit unsigned integer.
Definition cxxaux.hh:24
uint32_t uint
Provide 'uint' as convenience type.
Definition cxxaux.hh:18
String json_stringify(const T &source, Writ::Flags flags=Writ::Flags(0))
Create JSON string from source.
Definition serialize.hh:530
MusicalTuning
Musical tunings, see: http://en.wikipedia.org/wiki/Musical_tuning.
Definition api.hh:83
const char * ase_build_id()
Provide a string containing the ASE library build id.
Definition platform.cc:841
T resize(T... args)
T size(T... args)
typedef uint8_t
strerror
Representation of one possible choice for selection properties.
Definition api.hh:96
uint64 location() const
Address of memory area.
Definition memory.cc:340
Block allocate(uint32 length) const
Create a memory block from cache-line aligned memory area, MT-Unsafe.
Definition memory.cc:371
void release(Block allocatedblock) const
Realease a previously allocated block, MT-Unsafe.
Definition memory.cc:380
Value type used to interface with various property types.
Definition value.hh:54
String as_string() const
Convert Value to a string, not very useful for RECORD or ARRAY.
Definition value.cc:95
typedef size_t