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.cpp145
1 files changed, 141 insertions, 4 deletions
diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp
index 4f19e9b5960..52f59f366f6 100644
--- a/src/lib/netlist/prg/nlwav.cpp
+++ b/src/lib/netlist/prg/nlwav.cpp
@@ -5,6 +5,7 @@
#include "plib/plists.h"
#include "plib/pstream.h"
#include "plib/poptions.h"
+#include "plib/ppmf.h"
#include "nl_setup.h"
class nlwav_options_t : public plib::options
@@ -15,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"),
@@ -23,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;
@@ -139,12 +142,114 @@ private:
};
-static void convert()
+class log_processor
+{
+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, 48000U);
+ 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;
@@ -226,10 +331,39 @@ static void convert()
}
}
+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]"));
}
@@ -262,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;
}