diff --git a/src/drone-software/src/acoustic/CMakeLists.txt b/src/drone-software/src/acoustic/CMakeLists.txt index e39566b..040dc88 100644 --- a/src/drone-software/src/acoustic/CMakeLists.txt +++ b/src/drone-software/src/acoustic/CMakeLists.txt @@ -208,7 +208,7 @@ if(BUILD_TESTS) endif() add_test(NAME classifier_cpp COMMAND test_classifier_cpp --model ${CMAKE_CURRENT_SOURCE_DIR}/models/gunshot_classifier.onnx - --wav ${CMAKE_CURRENT_SOURCE_DIR}/dataset/binary/train/ambient/drone_noise_simulated.wav) + --wav ${CMAKE_CURRENT_SOURCE_DIR}/dataset/binary/val/ambient/drone_noise_val_000.wav) endif() endif() diff --git a/src/drone-software/src/acoustic/build/demo_offline.exe b/src/drone-software/src/acoustic/build/demo_offline.exe index 1a4091a..84227da 100644 Binary files a/src/drone-software/src/acoustic/build/demo_offline.exe and b/src/drone-software/src/acoustic/build/demo_offline.exe differ diff --git a/src/drone-software/src/acoustic/build/extract_mel_cpp.exe b/src/drone-software/src/acoustic/build/extract_mel_cpp.exe index 4a04e4e..6077e2b 100644 Binary files a/src/drone-software/src/acoustic/build/extract_mel_cpp.exe and b/src/drone-software/src/acoustic/build/extract_mel_cpp.exe differ diff --git a/src/drone-software/src/acoustic/build/test_classifier_cpp.exe b/src/drone-software/src/acoustic/build/test_classifier_cpp.exe index 3320b8a..46a1f6f 100644 Binary files a/src/drone-software/src/acoustic/build/test_classifier_cpp.exe and b/src/drone-software/src/acoustic/build/test_classifier_cpp.exe differ diff --git a/src/drone-software/src/acoustic/build/test_core_lib.exe b/src/drone-software/src/acoustic/build/test_core_lib.exe index 7e1fbd0..19802a2 100644 Binary files a/src/drone-software/src/acoustic/build/test_core_lib.exe and b/src/drone-software/src/acoustic/build/test_core_lib.exe differ diff --git a/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h b/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h index 5898cb5..5a54823 100644 --- a/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h +++ b/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h @@ -20,8 +20,6 @@ public: ~WavFileSource(); bool open(); - bool parse_wav_header(); - void resample_if_needed(std::vector& mono, int src_rate, int dst_rate); std::size_t read(std::vector>& out, std::size_t max_samples); void close(); @@ -32,6 +30,8 @@ public: bool is_open() const { return fp_ != nullptr; } private: + bool parse_wav_header(); + void resample_if_needed(std::vector& mono, int src_rate, int dst_rate); std::string path_; int target_sample_rate_; std::FILE* fp_; diff --git a/src/drone-software/src/acoustic/src/core/gunshot_classifier.cpp b/src/drone-software/src/acoustic/src/core/gunshot_classifier.cpp index 8f6d33f..814c34b 100644 --- a/src/drone-software/src/acoustic/src/core/gunshot_classifier.cpp +++ b/src/drone-software/src/acoustic/src/core/gunshot_classifier.cpp @@ -33,32 +33,67 @@ struct GunshotClassifier::Impl { bool LoadLabelMap(const std::string& path) { std::ifstream f(path); if (!f) return false; - std::string line; + std::string content((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); labels.clear(); - while (std::getline(f, line)) { - // Parse "index: label" format - size_t pos = line.find(':'); - if (pos == std::string::npos) continue; - int idx = 0; - try { - idx = std::stoi(line.substr(0, pos)); - } catch (...) { - continue; - } - std::string label = line.substr(pos + 1); - // trim whitespace - size_t start = label.find_first_not_of(" \t\r\n"); - size_t end = label.find_last_not_of(" \t\r\n"); - if (start != std::string::npos && end != std::string::npos) { - label = label.substr(start, end - start + 1); - } else { - label.clear(); + + // Try simple JSON object format: {"0": "ambient", "1": "threat"} + if (content.find('{') != std::string::npos) { + size_t pos = 0; + while ((pos = content.find('"', pos)) != std::string::npos) { + size_t key_start = pos + 1; + size_t key_end = content.find('"', key_start); + if (key_end == std::string::npos) break; + std::string key = content.substr(key_start, key_end - key_start); + int idx = -1; + try { idx = std::stoi(key); } catch (...) {} + + size_t colon = content.find(':', key_end); + if (colon == std::string::npos) break; + size_t val_quote = content.find('"', colon); + if (val_quote == std::string::npos) break; + size_t val_end = content.find('"', val_quote + 1); + if (val_end == std::string::npos) break; + std::string label = content.substr(val_quote + 1, val_end - val_quote - 1); + + if (idx >= 0) { + if (idx >= static_cast(labels.size())) labels.resize(idx + 1); + labels[idx] = label; + } + pos = val_end + 1; } - if (idx >= static_cast(labels.size())) { - labels.resize(idx + 1); + } else { + // Fallback: "index: label" line format + size_t line_start = 0; + while (line_start < content.size()) { + size_t line_end = content.find('\n', line_start); + if (line_end == std::string::npos) line_end = content.size(); + std::string line = content.substr(line_start, line_end - line_start); + line_start = line_end + 1; + + std::size_t pos = line.find(':'); + if (pos == std::string::npos) continue; + int idx = 0; + try { + idx = std::stoi(line.substr(0, pos)); + } catch (...) { + continue; + } + std::string label = line.substr(pos + 1); + std::size_t start = label.find_first_not_of(" \t\r\n"); + std::size_t end = label.find_last_not_of(" \t\r\n"); + if (start != std::string::npos && end != std::string::npos) { + label = label.substr(start, end - start + 1); + } else { + label.clear(); + } + if (idx >= static_cast(labels.size())) { + labels.resize(idx + 1); + } + labels[idx] = label; } - labels[idx] = label; } + // Remove empty entries and compact std::vector cleaned; for (const auto& l : labels) {