| 37 | } // namespace |
| 38 | |
| 39 | int main(int argc, char ** argv) { |
| 40 | if (argc < 5) { |
| 41 | std::cerr << "Usage: stft_parity_dump <wav> <kind:stft> <out_f32> <out_shape_i64>" |
| 42 | " [--preemphasis VALUE] [--n-fft N] [--hop-length N] [--win-length N] [--pad-mode constant|reflect]\n"; |
| 43 | return 1; |
| 44 | } |
| 45 | |
| 46 | const std::filesystem::path wav_path(argv[1]); |
| 47 | const std::string kind(argv[2]); |
| 48 | const std::filesystem::path out_f32(argv[3]); |
| 49 | const std::filesystem::path out_shape(argv[4]); |
| 50 | |
| 51 | float preemphasis = 0.0f; |
| 52 | int64_t n_fft = 512; |
| 53 | int64_t hop_length = 160; |
| 54 | int64_t win_length = 400; |
| 55 | engine::audio::STFTPadMode pad_mode = engine::audio::STFTPadMode::Constant; |
| 56 | for (int i = 5; i < argc; i += 2) { |
| 57 | if (i + 1 >= argc) { |
| 58 | throw std::runtime_error("missing value for trailing option"); |
| 59 | } |
| 60 | const std::string option(argv[i]); |
| 61 | const std::string value(argv[i + 1]); |
| 62 | if (option == "--preemphasis") { |
| 63 | preemphasis = std::strtof(value.c_str(), nullptr); |
| 64 | } else if (option == "--n-fft") { |
| 65 | n_fft = std::strtoll(value.c_str(), nullptr, 10); |
| 66 | } else if (option == "--hop-length") { |
| 67 | hop_length = std::strtoll(value.c_str(), nullptr, 10); |
| 68 | } else if (option == "--win-length") { |
| 69 | win_length = std::strtoll(value.c_str(), nullptr, 10); |
| 70 | } else if (option == "--pad-mode") { |
| 71 | if (value == "constant") { |
| 72 | pad_mode = engine::audio::STFTPadMode::Constant; |
| 73 | } else if (value == "reflect") { |
| 74 | pad_mode = engine::audio::STFTPadMode::Reflect; |
| 75 | } else { |
| 76 | throw std::runtime_error("pad-mode must be 'constant' or 'reflect'"); |
| 77 | } |
| 78 | } else { |
| 79 | throw std::runtime_error("unknown option: " + option); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | auto wav = engine::audio::read_wav_f32(wav_path); |
| 84 | if (wav.channels != 1) { |
| 85 | throw std::runtime_error("stft_parity_dump requires mono WAV"); |
| 86 | } |
| 87 | |
| 88 | if (preemphasis != 0.0f && !wav.samples.empty()) { |
| 89 | for (size_t i = wav.samples.size() - 1; i >= 1; --i) { |
| 90 | wav.samples[i] = wav.samples[i] - preemphasis * wav.samples[i - 1]; |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | const engine::audio::STFTConfig config{ |
| 95 | n_fft, |
| 96 | hop_length, |
nothing calls this directly
no test coverage detected