Files
SonicForgeStudio/native_host/tests/native_mixer_test.cpp
T

85 lines
2.7 KiB
C++

// native_mixer_test.cpp — golden test driver cho NativeMixer (T13).
//
// Đọc input raw float32 interleaved stereo, áp NativeMixer (track gain/pan +
// master limiter) theo argv, ghi output raw float32 interleaved. Python
// (test_native_mixer_golden.py) so RMS/peak với reference server pipeline.
//
// Usage: native_mixer_test.exe <in.raw> <out.raw> <gainDb> <pan> <limActive> <thresholdDb>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <vector>
#include "NativeMixer.h"
using sonicforge::int32;
int main (int argc, char** argv)
{
if (argc < 7)
{
std::fprintf (stderr, "usage: native_mixer_test in.raw out.raw gainDb pan limActive thresholdDb\n");
return 2;
}
const char* inPath = argv[1];
const char* outPath = argv[2];
const float gainDb = static_cast<float> (std::atof (argv[3]));
const float pan = static_cast<float> (std::atof (argv[4]));
const int32 limActive = std::atoi (argv[5]);
const float thresholdDb = static_cast<float> (std::atof (argv[6]));
FILE* f = std::fopen (inPath, "rb");
if (!f)
{
std::fprintf (stderr, "cannot open %s\n", inPath);
return 2;
}
std::fseek (f, 0, SEEK_END);
const long nBytes = std::ftell (f);
std::fseek (f, 0, SEEK_SET);
if (nBytes <= 0 || (nBytes % 8) != 0)
{
std::fprintf (stderr, "bad input size %ld\n", nBytes);
std::fclose (f);
return 2;
}
std::vector<float> buf (static_cast<size_t> (nBytes) / sizeof (float));
if (std::fread (buf.data (), sizeof (float), buf.size (), f) != buf.size ())
{
std::fprintf (stderr, "short read\n");
std::fclose (f);
return 2;
}
std::fclose (f);
const int32 frames = static_cast<int32> (buf.size () / 2);
std::vector<float> inL (static_cast<size_t> (frames));
std::vector<float> inR (static_cast<size_t> (frames));
for (int32 i = 0; i < frames; ++i)
{
inL[static_cast<size_t> (i)] = buf[static_cast<size_t> (2 * i)];
inR[static_cast<size_t> (i)] = buf[static_cast<size_t> (2 * i + 1)];
}
sonicforge::NativeMixer mixer;
mixer.setTrack (sonicforge::TrackGainPan::fromDbPan (gainDb, pan));
mixer.setLimiter (limActive != 0, thresholdDb);
mixer.processInPlace (inL.data (), inR.data (), frames);
for (int32 i = 0; i < frames; ++i)
{
buf[static_cast<size_t> (2 * i)] = inL[static_cast<size_t> (i)];
buf[static_cast<size_t> (2 * i + 1)] = inR[static_cast<size_t> (i)];
}
FILE* g = std::fopen (outPath, "wb");
if (!g)
{
std::fprintf (stderr, "cannot write %s\n", outPath);
return 2;
}
std::fwrite (buf.data (), sizeof (float), buf.size (), g);
std::fclose (g);
return 0;
}