Grammar rule executor — concatenative reconstruct into DynamicSoundStream.
219 {
220 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
221 const auto& regions = datum.data.regions;
222
223 if (regions.empty()) {
224 error<std::runtime_error>(Journal::Component::Yantra, Journal::Context::ComputeMatrix,
225 std::source_location::current(), "reconstruct_grains_stream: RegionGroup contains no grains");
226 }
227
228 if (!datum.container || !*datum.container) {
229 error<std::runtime_error>(Journal::Component::Yantra, Journal::Context::ComputeMatrix,
230 std::source_location::current(), "reconstruct_grains_stream: no source container in datum");
231 }
232
233 auto source = *datum.container;
234 const auto num_ch = static_cast<uint32_t>(source->get_structure().get_channel_count());
235 const uint32_t sample_rate = [&]() -> uint32_t {
236 if (auto sc = std::dynamic_pointer_cast<Kakshya::SoundStreamContainer>(source))
237 return sc->get_sample_rate();
238 return 48000U;
239 }();
240
241 const auto grain_sz = safe_any_cast_or_default<uint32_t>(
242 datum.data.get_attribute<uint32_t>("grain_size").has_value()
243 ? std::any(datum.data.get_attribute<uint32_t>("grain_size").value())
245 1024U);
246
247 std::vector<std::vector<double>> channel_data(num_ch);
248 for (uint32_t ch = 0; ch < num_ch; ++ch)
249 channel_data[ch].reserve(regions.size() * grain_sz);
250
251 Kakshya::iterate_region_channels(regions, source, num_ch, {},
252 [&channel_data](size_t , uint32_t ch, std::span<double> samples) {
253 channel_data[ch].insert(channel_data[ch].end(), samples.begin(), samples.end());
254 });
255
256 auto stream = std::make_shared<Kakshya::DynamicSoundStream>(sample_rate, num_ch);
257
258 std::vector<std::span<const double>> spans;
259 spans.reserve(num_ch);
260 for (auto& ch : channel_data)
261 spans.emplace_back(ch);
262
263 stream->write_frames(spans, 0);
264
265 return Datum<std::shared_ptr<Kakshya::SignalSourceContainer>> {
266 std::dynamic_pointer_cast<Kakshya::SignalSourceContainer>(stream), {}
267 };
268};