// framed_test.cpp — рендер входа через SpectralProcessor (real mask chain). // Usage: framed_test [fc[,q[,sens]] ...] #include "spectral.hpp" #include #include #include #include #include static bool load_wav(const char* path, std::vector& out, int& sr) { FILE* f = fopen(path, "rb"); if (!f) return false; char hdr[44]; if (fread(hdr, 1, 44, f) != 44) return false; sr = *(int*)(hdr + 24); int ch = *(short*)(hdr + 22); int bits = *(short*)(hdr + 34); int data = *(int*)(hdr + 40); int n = data / (ch * (bits / 8)); std::vector raw(n * ch); fread(raw.data(), 2, n * ch, f); fclose(f); out.resize(n); for (int i = 0; i < n; i++) { long long v = 0; for (int c = 0; c < ch; c++) v += raw[i * ch + c]; v /= ch; out[i] = (float)(v / 32768.0); } return true; } static bool save_wav(const char* path, const std::vector& x, int sr) { FILE* f = fopen(path, "wb"); if (!f) return false; int data = (int)(x.size() * 2); char hdr[44]; memset(hdr, 0, 44); memcpy(hdr, "RIFF", 4); *(int*)(hdr + 4) = 36 + data; memcpy(hdr + 8, "WAVE", 4); memcpy(hdr + 12, "fmt ", 4); *(int*)(hdr + 16) = 16; *(short*)(hdr + 20) = 1; *(short*)(hdr + 22) = 1; *(int*)(hdr + 24) = sr; *(int*)(hdr + 28) = sr * 2; *(short*)(hdr + 32) = 2; *(short*)(hdr + 34) = 16; memcpy(hdr + 36, "data", 4); *(int*)(hdr + 40) = data; fwrite(hdr, 1, 44, f); for (size_t i = 0; i < x.size(); i++) { short v = (short)(std::max(-1.0f, std::min(1.0f, x[i])) * 32767.0f); fwrite(&v, 2, 1, f); } fclose(f); return true; } int main(int argc, char** argv) { if (argc < 3) { fprintf(stderr, "usage: %s in.wav out.wav [fc,q,sens] ...\n", argv[0]); return 1; } std::vector x; int sr; if (!load_wav(argv[1], x, sr)) { fprintf(stderr, "cannot load %s\n", argv[1]); return 1; } std::vector bands; if (argc >= 4 && strchr(argv[3], ',')) { // comma form: "fc,q,sens[,scale]" float fc, q, sens, scl = 1.0f; // parse first 3 int n = sscanf(argv[3], "%f,%f,%f,%f", &fc, &q, &sens, &scl); DetectorBand b; b.fc = fc; b.q = q; b.sens = sens; b.level_scale = scl; bands.push_back(b); } else { for (int i = 3; i + 2 < argc; i += 3) { DetectorBand b; b.fc = (float)atof(argv[i]); b.q = (float)atof(argv[i + 1]); b.sens = (float)atof(argv[i + 2]); if (i + 3 < argc) b.level_scale = (float)atof(argv[i + 3]); bands.push_back(b); } } if (bands.empty()) bands.push_back({1000.0f, 1.0f, 12.0f}); SpectralProcessor sp(2048, 512); sp.setDetectorParams(bands); std::vector y(x.size()); const size_t BLK = 1 << 16; std::vector inb(BLK), outb(BLK); for (size_t s = 0; s < x.size(); s += BLK) { size_t n = std::min(BLK, x.size() - s); memcpy(inb.data(), x.data() + s, n * sizeof(float)); for (size_t i = n; i < BLK; i++) inb[i] = 0.0f; sp.processBlock(inb.data(), outb.data(), BLK, 1); memcpy(y.data() + s, outb.data(), n * sizeof(float)); } save_wav(argv[2], y, sr); printf("wrote %s (%zu samples sr=%d, %zu bands)\n", argv[2], y.size(), sr, bands.size()); return 0; }