EchoMap 2026-07-25 6d3977c
An experimental cross-platform digital signal processing application for sound-source localisation.
Loading...
Searching...
No Matches
anonymous_namespace{JSONFullDeserialiser.cpp} Namespace Reference

Free helper functions for simdjson customisation points. More...

Functions

auto get_signals (simdjson::ondemand::object &root, const echomap::Project &project, std::unordered_map< std::string_view, echomap::id_type > &loaded)

Variables

echomap::Workerparent_worker = nullptr

Detailed Description

Free helper functions for simdjson customisation points.

Function Documentation

◆ get_signals()

auto anonymous_namespace{JSONFullDeserialiser.cpp}::get_signals ( simdjson::ondemand::object & root,
const echomap::Project & project,
std::unordered_map< std::string_view, echomap::id_type > & loaded )

Definition at line 23 of file JSONFullDeserialiser.cpp.

30{
31 // Step 1. Create our factories which detain only the signal metadata (sample rate, etc.) and source information.
33 if (const auto error = root["signals"].get(factories))
34 return error;
35
36 /*
37 * Step 2. Group the factories by the source filenames of the signals they're constructing.
38 *
39 * The key of the map is the source filename, and the value is a bijective correspondence between the channel in the
40 * wave file and the factory designated to load the channel at the index.
41 *
42 * That is, the first slot owns the factory for constructing the signal on Channel 1, the second for Channel 2, etc.
43 * If there is a gap, the entry is the empty unique_ptr<SignalFactory>, such that it equals nullptr.
44 */
46
47 for (auto factory : factories | std::views::as_rvalue) {
48 const auto& signal = factory->observe_signal();
49 if (!loaded.emplace(signal.get_name(), signal.get_id()).second)
50 throw std::runtime_error(std::format("Project contains duplicate signal {}.", signal.get_name()));
51
52 if (signal.observe_source().has_value()) {
53 /*
54 * If the Signal has a Source, it comes from the filesystem. Register the Signal as a destination for its
55 * source file for its channel number.
56 */
57 auto& slot_vector = slots[signal.observe_source()->path.c_str()];
58 const auto channel_num = signal.observe_source()->channel;
59
60 // Reminder: channel numbers are 1-based.
61 if (channel_num > slot_vector.size())
62 slot_vector.resize(channel_num);
63 else if (slot_vector[channel_num - 1] != nullptr)
66 "Both signals {} and {} have requested the same channel {} from {}.",
67 slot_vector[channel_num - 1]->observe_signal().get_name(),
68 signal.get_name(),
69 channel_num,
70 signal.observe_source()->path.c_str()
71 )
72 );
73
74 slot_vector[channel_num - 1] = std::move(factory);
75 }
76 }
77
78 /*
79 * Step 3. Once we have the factories grouped by source, and put into the bijective correspondence with the channel
80 * numbers, submit a task to the thread-safe Worker for each distinct file. The task takes ownership of the
81 * factories.
82 *
83 * The results will own the signal objects produced by the factories, which can be added to the project by the
84 * EchoMap controller (or whoever is the nominated consumer).
85 */
86 if (!slots.empty()) {
87 if (parent_worker == nullptr)
88 throw std::runtime_error(
90 "Need to despatch extra work to load {}, but a suitable Worker is unavailable.",
91 project.get_name()
92 )
93 );
94
95 for (auto&& [file_path, slot_vector] : slots)
96 parent_worker->submit(
97 std::make_unique<echomap::LoadSignalFileTask>(project.get_id(), file_path, std::move(slot_vector))
98 );
99 }
100
101 return simdjson::SUCCESS;
102}
T emplace(T... args)
T empty(T... args)
T format(T... args)
T make_unique(T... args)

Variable Documentation

◆ parent_worker

echomap::Worker* anonymous_namespace{JSONFullDeserialiser.cpp}::parent_worker = nullptr

Definition at line 21 of file JSONFullDeserialiser.cpp.