diff options
Diffstat (limited to 'src/lib/netlist/prg/nlwav.cpp')
-rw-r--r-- | src/lib/netlist/prg/nlwav.cpp | 145 |
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; } |