EchoMap 2026-07-25 6d3977c
An experimental cross-platform digital signal processing application for sound-source localisation.
Loading...
Searching...
No Matches
JSONDeserialiserHelpers.hpp
Go to the documentation of this file.
1
9
10#ifndef ECHOMAP_JSONDESERIALISERHELPERS_HPP
11#define ECHOMAP_JSONDESERIALISERHELPERS_HPP
12
13#include <simdjson.h>
14
15#include <unordered_map>
16
17#include "../Sensor.hpp"
19
20namespace echomap
21{
22
23class Project;
24class Signal;
25
32{
33public:
34 template <typename simdjson_value> // NOLINT(*-identifier-naming)
35 static simdjson::error_code get_root(
36 simdjson::ondemand::object& root,
37 simdjson_value& value
38 )
39 {
40 auto error = value.get_object().get(root);
41 if (error)
42 return error;
43
44 // Schema version check.
45 static constexpr unsigned int expected_schema_version = 1;
46 unsigned int actual_schema_version = 0;
47
48 if ((error = root["schema_version"].get(actual_schema_version)))
49 return error;
50
51 if (actual_schema_version != expected_schema_version)
54 "Project file was saved in an incompatible version {} (expected {}).",
55 actual_schema_version,
56 expected_schema_version
57 )
58 );
59
60 return simdjson::SUCCESS;
61 }
62
63 static simdjson::error_code get_metadata(
64 simdjson::ondemand::object& root,
65 Project& project
66 );
67
68 static simdjson::error_code get_sensors(
69 simdjson::ondemand::object& root,
70 Project& project,
73 id_type>& loaded
74 );
75
76 static simdjson::error_code get_mappings(
77 simdjson::ondemand::object& root,
78 Project& project,
81 id_type>& signals,
84 id_type>& sensors
85 );
86
87 static void verify_sample_count(
88 std::uint64_t reported_sample_count,
89 const Signal& signal
90 );
91
92 template <typename ValueT>
93 static simdjson::error_code get_or_default(
94 simdjson::ondemand::object& obj,
95 const std::string_view key,
96 ValueT& out,
97 const ValueT& fallback
98 )
99 {
100 auto field = obj[key];
101
102 if (field.error() == simdjson::NO_SUCH_FIELD) {
103 out = fallback;
104 return simdjson::SUCCESS;
105 }
106
107 return field.get(out);
108 }
109
110 static simdjson::error_code get_uniformly_sampled_signal_source(
111 simdjson::ondemand::object& source,
112 const SignalFactory& signal_factory
113 );
114
115 static simdjson::error_code get_variably_sampled_signal_source(
116 simdjson::ondemand::object& source,
117 const SignalFactory& signal_factory
118 );
119};
120
121} // namespace echomap
122
123namespace simdjson
124{
125
126template <typename simdjson_value>
127auto tag_invoke(
128 deserialize_tag /*unused*/,
129 simdjson_value& value,
130 echomap::SignalFactory& signal_factory
131)
132{
133 ondemand::object root;
134 auto error = value.get_object().get(root);
135 if (error)
136 return error;
137
138 std::string_view name;
139 if ((error = root["name"].get(name)))
140 return error;
141 signal_factory.set_signal_name(name);
142
143 ondemand::object source;
144 if ((error = root["source"].get_object().get(source)))
145 return error;
146
147 std::string_view kind;
148 if ((error = source["kind"].get(kind)))
149 return error;
150
151 if (kind == "filesystem") {
152 // Signals sourced from the file system are not loaded by the parser; we just populate the source information.
153
154 std::string_view path;
155 if ((error = source["path"].get(path)))
156 return error;
157
158 std::size_t channel_num;
159 if ((error = source["channel"].get(channel_num)))
160 return error;
161
162 signal_factory.set_source(path, channel_num);
163 } else if (kind == "embeddedUniform") {
164 // Embedded signals with uniform sampling are constructed by the parser with the mandatory timing information.
165 if ((error = echomap::JSONDeserialiserHelpers::get_uniformly_sampled_signal_source(source, signal_factory)))
166 return error;
167 } else if (kind == "embeddedVariable") {
168 // Embedded signals with variable sampling are constructed by the parser with the optional timing information.
169 if ((error = echomap::JSONDeserialiserHelpers::get_variably_sampled_signal_source(source, signal_factory)))
170 return error;
171 } else
172 throw std::runtime_error(std::format("Signal {} specifies unknown source kind \"{}\".", name, kind));
173
174 return SUCCESS;
175}
176
177template <typename simdjson_value>
178static error_code tag_invoke(
179 deserialize_tag /*unused*/,
180 simdjson_value& value,
181 echomap::Sensor& sensor
182)
183{
184 ondemand::object root;
185 auto error = value.get_object().get(root);
186 if (error)
187 return error;
188
189 std::string_view name;
190 if ((error = root["name"].get(name)))
191 return error;
192 sensor.set_name(name);
193
194 ondemand::object position;
195 if ((error = root["position"].get_object().get(position)))
196 return error;
197
198 if ((error = position["x"].get(sensor.position.x)))
199 return error;
200 if ((error = position["y"].get(sensor.position.y)))
201 return error;
202 if ((error = position["z"].get(sensor.position.z)))
203 return error;
204
205 ondemand::object colour;
206 if ((error = root["colour"].get_object().get(colour)))
207 return error;
208
209 if ((error = colour["r"].get(sensor.colour.r)))
210 return error;
211 if ((error = colour["g"].get(sensor.colour.g)))
212 return error;
213 if ((error = colour["b"].get(sensor.colour.b)))
214 return error;
215 if ((error = colour["a"].get(sensor.colour.a)))
216 return error;
217
218 return SUCCESS;
219}
220
221} // namespace simdjson
222
223#endif // ECHOMAP_JSONDESERIALISERHELPERS_HPP
Wave file specification.
Provides a set of static helpers for parsing Project fields with SIMDJSON.
Provides various convenience functions for constructing Signal objects in exotic ways.
A single channel of discretely sampled audio data.
Definition Signal.hpp:40
T format(T... args)
The main EchoMap outermost namespace for all non-exported symbols.
float b
The blue component in the range [0, 1].
Definition Colour.hpp:23
float a
The alpha extent in the range [0, 1].
Definition Colour.hpp:24
float g
The green component in the range [0, 1].
Definition Colour.hpp:22
float r
The red component in the range [0, 1].
Definition Colour.hpp:21
float y
The Y co-ordinate.
Definition Position.hpp:22
float x
The X co-ordinate.
Definition Position.hpp:21
float z
The Z co-ordinate.
Definition Position.hpp:23