summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/prg/nlwav.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/prg/nlwav.cpp')
-rw-r--r--src/lib/netlist/prg/nlwav.cpp170
1 files changed, 153 insertions, 17 deletions
diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp
index 44adf2b3508..52f59f366f6 100644
--- a/src/lib/netlist/prg/nlwav.cpp
+++ b/src/lib/netlist/prg/nlwav.cpp
@@ -1,13 +1,12 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
-#include <plib/poptions.h>
-#include <cstdio>
#include <cstring>
#include "plib/pstring.h"
#include "plib/plists.h"
#include "plib/pstream.h"
+#include "plib/poptions.h"
+#include "plib/ppmf.h"
#include "nl_setup.h"
-#include <memory>
class nlwav_options_t : public plib::options
{
@@ -17,6 +16,7 @@ public:
opt_inp(*this, "i", "input", "-", "input file"),
opt_out(*this, "o", "output", "-", "output file"),
opt_amp(*this, "a", "amp", 10000.0, "amplification after mean correction"),
+ opt_rate(*this, "r", "rate", 48000, "sample rate of output file"),
opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
opt_quiet(*this,"q", "quiet", "be quiet - no warnings"),
opt_version(*this, "", "version", "display version and exit"),
@@ -25,6 +25,7 @@ public:
plib::option_str opt_inp;
plib::option_str opt_out;
plib::option_double opt_amp;
+ plib::option_long opt_rate;
plib::option_bool opt_verb;
plib::option_bool opt_quiet;
plib::option_bool opt_version;
@@ -35,8 +36,8 @@ plib::pstdin pin_strm;
plib::pstdout pout_strm;
plib::pstderr perr_strm;
-plib::pstream_fmt_writer_t pout(pout_strm);
-plib::pstream_fmt_writer_t perr(perr_strm);
+plib::putf8_fmt_writer pout(pout_strm);
+plib::putf8_fmt_writer perr(perr_strm);
nlwav_options_t opts;
@@ -141,11 +142,114 @@ private:
};
-static void convert()
+class log_processor
{
- plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : new plib::pofilestream(opts.opt_out()));
- plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : new plib::pifilestream(opts.opt_inp()));
- wav_t *wo = new wav_t(*fo, 48000);
+public:
+ typedef plib::pmfp<void, double, double> callback_type;
+ log_processor(plib::pistream &is, callback_type cb) : m_is(is), m_cb(cb) { }
+
+ void process()
+ {
+ plib::putf8_reader reader(m_is);
+ pstring line;
+
+ while(reader.readline(line))
+ {
+ double t = 0.0; double v = 0.0;
+ sscanf(line.c_str(), "%lf %lf", &t, &v);
+ m_cb(t, v);
+ }
+ }
+
+private:
+ plib::pistream &m_is;
+ callback_type m_cb;
+};
+
+struct aggregator
+{
+ typedef plib::pmfp<void, double, double> callback_type;
+
+ aggregator(double quantum, callback_type cb)
+ : m_quantum(quantum)
+ , m_cb(cb)
+ , ct(0.0)
+ , lt(0.0)
+ , outsam(0.0)
+ , cursam(0.0)
+ { }
+ void process(double time, double val)
+ {
+ while (time >= ct)
+ {
+ outsam += (ct - lt) * cursam;
+ outsam = outsam / m_quantum;
+ m_cb(ct, outsam);
+ outsam = 0.0;
+ lt = ct;
+ ct += m_quantum;
+ }
+ outsam += (time-lt)*cursam;
+ lt = time;
+ cursam = val;
+ }
+
+private:
+ double m_quantum;
+ callback_type m_cb;
+ double ct;
+ double lt;
+ double outsam;
+ double cursam;
+};
+
+class wavwriter
+{
+public:
+ wavwriter(plib::postream &fo, unsigned sample_rate, double ampa)
+ : mean(0.0)
+ , means(0.0)
+ , maxsam(-1e9)
+ , minsam(1e9)
+ , n(0)
+ , m_fo(fo)
+ , amp(ampa)
+ , m_wo(m_fo, sample_rate)
+ { }
+
+ void process(double time, double outsam)
+ {
+ means += outsam;
+ maxsam = std::max(maxsam, outsam);
+ minsam = std::min(minsam, outsam);
+ n++;
+ //mean = means / (double) n;
+ mean += 5.0 / static_cast<double>(m_wo.sample_rate()) * (outsam - mean);
+
+ outsam = (outsam - mean) * amp;
+ outsam = std::max(-32000.0, outsam);
+ outsam = std::min(32000.0, outsam);
+ m_wo.write_sample(static_cast<int>(outsam));
+ }
+
+ double mean;
+ double means;
+ double maxsam;
+ double minsam;
+ std::size_t n;
+
+private:
+ plib::postream &m_fo;
+ double amp;
+ wav_t m_wo;
+};
+
+static void convert(long sample_rate)
+{
+ plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opts.opt_out()));
+ plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : plib::palloc<plib::pifilestream>(opts.opt_inp()));
+ plib::putf8_reader reader(*fin);
+ wav_t *wo = plib::palloc<wav_t>(*fo, static_cast<unsigned>(sample_rate));
double dt = 1.0 / static_cast<double>(wo->sample_rate());
double ct = dt;
@@ -162,7 +266,7 @@ static void convert()
//short sample = 0;
pstring line;
- while(fin->readline(line))
+ while(reader.readline(line))
{
#if 1
double t = 0.0; double v = 0.0;
@@ -212,11 +316,11 @@ static void convert()
//printf("%f %f\n", t, v);
#endif
}
- delete wo;
+ plib::pfree(wo);
if (opts.opt_inp() != "-")
- delete fin;
+ plib::pfree(fin);
if (opts.opt_out() != "-")
- delete fo;
+ plib::pfree(fo);
if (!opts.opt_quiet())
{
@@ -227,10 +331,39 @@ static void convert()
}
}
-static void usage(plib::pstream_fmt_writer_t &fw)
+static void convert1(long sample_rate)
+{
+ plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opts.opt_out()));
+ plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : plib::palloc<plib::pifilestream>(opts.opt_inp()));
+
+ double dt = 1.0 / static_cast<double>(sample_rate);
+
+ wavwriter *wo = plib::palloc<wavwriter>(*fo, static_cast<unsigned>(sample_rate), opts.opt_amp());
+ aggregator ag(dt, aggregator::callback_type(&wavwriter::process, wo));
+ log_processor lp(*fin, log_processor::callback_type(&aggregator::process, &ag));
+
+ lp.process();
+
+ if (!opts.opt_quiet())
+ {
+ perr("Mean (low freq filter): {}\n", wo->mean);
+ perr("Mean (static): {}\n", wo->means / static_cast<double>(wo->n));
+ perr("Amp + {}\n", 32000.0 / (wo->maxsam - wo->mean));
+ perr("Amp - {}\n", -32000.0 / (wo->minsam - wo->mean));
+ }
+
+ plib::pfree(wo);
+ if (opts.opt_inp() != "-")
+ plib::pfree(fin);
+ if (opts.opt_out() != "-")
+ plib::pfree(fo);
+
+}
+
+static void usage(plib::putf8_fmt_writer &fw)
{
fw("{}\n", opts.help("Convert netlist log files into wav files.\n",
- "nltool [options]").c_str());
+ "nltool [options]"));
}
@@ -255,7 +388,7 @@ int main(int argc, char *argv[])
{
pout(
"nlwav (netlist) 0.1\n"
- "Copyright (C) 2016 Couriersud\n"
+ "Copyright (C) 2017 Couriersud\n"
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n\n"
@@ -263,7 +396,10 @@ int main(int argc, char *argv[])
return 0;
}
- convert();
+ if ((1))
+ convert1(opts.opt_rate());
+ else
+ convert(opts.opt_rate());
return 0;
}