225 auto [numeric_data, info] = OperationHelper::extract_structured_double(
const_cast<input_type&
>(input));
228 std::vector<std::span<const double>> channels;
229 channels.reserve(numeric_data.size());
230 for (
auto& s : numeric_data)
231 channels.emplace_back(s.data(), s.size());
233 std::vector<std::vector<double>> extracted_data;
237 case ExtractionMethod::HIGH_ENERGY_DATA:
239 this->
template get_parameter_or_default<double>(
"energy_threshold", 0.1),
240 m_window_size, m_hop_size);
243 case ExtractionMethod::PEAK_DATA:
245 this->
template get_parameter_or_default<double>(
"threshold", 0.1),
246 this->
template get_parameter_or_default<double>(
"min_distance", 10.0),
247 this->
template get_parameter_or_default<uint32_t>(
"region_size", 256));
250 case ExtractionMethod::OUTLIER_DATA:
252 this->
template get_parameter_or_default<double>(
"std_dev_threshold", 2.0),
253 m_window_size, m_hop_size);
256 case ExtractionMethod::HIGH_SPECTRAL_DATA:
258 this->
template get_parameter_or_default<double>(
"spectral_threshold", 0.1),
259 m_window_size, m_hop_size);
262 case ExtractionMethod::ABOVE_MEAN_DATA:
264 this->
template get_parameter_or_default<double>(
"mean_multiplier", 1.5),
265 m_window_size, m_hop_size);
268 case ExtractionMethod::OVERLAPPING_WINDOWS:
271 this->
template get_parameter_or_default<double>(
"overlap", 0.5));
274 case ExtractionMethod::ZERO_CROSSING_DATA:
276 this->
template get_parameter_or_default<double>(
"threshold", 0.0),
277 this->
template get_parameter_or_default<double>(
"min_distance", 1.0),
278 this->
template get_parameter_or_default<uint32_t>(
"region_size", 1));
281 case ExtractionMethod::SILENCE_DATA:
283 this->
template get_parameter_or_default<double>(
"silence_threshold", 0.01),
284 this->
template get_parameter_or_default<uint32_t>(
"min_duration", 1024),
285 m_window_size, m_hop_size);
288 case ExtractionMethod::ONSET_DATA:
290 this->
template get_parameter_or_default<double>(
"threshold", 0.3),
291 this->
template get_parameter_or_default<uint32_t>(
"region_size", 512),
292 this->
template get_parameter_or_default<uint32_t>(
"fft_window_size", 1024),
297 error<std::invalid_argument>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(),
"Unknown extraction method");
300 output_type output = this->convert_result(extracted_data, structure_info);
302 output.template set_metadata<std::string>(
"extractor_type",
"FeatureExtractor");
303 output.template set_metadata<std::string>(
"extraction_method", method_to_string(m_method));
304 output.template set_metadata<uint32_t>(
"window_size",
static_cast<uint32_t
>(m_window_size));
305 output.template set_metadata<uint32_t>(
"hop_size",
static_cast<uint32_t
>(m_hop_size));
306 output.template set_metadata<size_t>(
"extracted_samples", extracted_data.size());
310 }
catch (
const std::exception& e) {
311 MF_ERROR(Journal::Component::Yantra, Journal::Context::ComputeMatrix,
"Feature extraction failed: {}", e.what());
321 if (name ==
"method") {
322 if (
auto* method_str = std::any_cast<std::string>(&value)) {
323 m_method = string_to_method(*method_str);
326 if (
auto* method_enum = std::any_cast<ExtractionMethod>(&value)) {
327 m_method = *method_enum;
330 error<std::invalid_argument>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(),
"Method parameter must be string or ExtractionMethod enum");
333 if (name ==
"window_size") {
334 if (
auto* size = std::any_cast<uint32_t>(&value)) {
335 m_window_size = *size;
336 validate_parameters();
340 if (name ==
"hop_size") {
341 if (
auto* size = std::any_cast<uint32_t>(&value)) {
343 validate_parameters();
348 base_type::set_extraction_parameter(name, std::move(value));
376 if (m_window_size == 0) {
377 error<std::invalid_argument>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(),
"Window size must be greater than 0");
379 if (m_hop_size == 0) {
380 error<std::invalid_argument>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(),
"Hop size must be greater than 0");
382 if (m_hop_size > m_window_size) {
383 error<std::invalid_argument>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(),
"Hop size should not exceed window size for optimal coverage");