diff options
| author | Vasile Vilvoiu <vasi@vilvoiu.ro> | 2021-07-16 21:00:28 +0300 |
|---|---|---|
| committer | Vasile Vilvoiu <vasi@vilvoiu.ro> | 2021-07-16 21:00:28 +0300 |
| commit | 68e6ebe24cb476997b2ddfc21a5b13fb6f332fa7 (patch) | |
| tree | 646db708a2db1b61904003c81a05b01358cdb4cc | |
| parent | b13609afcdf66d781db70fb75f6869a052a49079 (diff) | |
Render texture onto window on each iteration.
Keep colormap in renderer so we don't pass the colormapped windows like
animals.
Pre-render empty window.
Fixes #15.
| -rw-r--r-- | src/color-map.cpp | 5 | ||||
| -rw-r--r-- | src/color-map.hpp | 7 | ||||
| -rw-r--r-- | src/live.cpp | 20 | ||||
| -rw-r--r-- | src/live.hpp | 2 | ||||
| -rw-r--r-- | src/renderer.cpp | 16 | ||||
| -rw-r--r-- | src/renderer.hpp | 3 | ||||
| -rw-r--r-- | src/specgram.cpp | 21 |
7 files changed, 44 insertions, 30 deletions
diff --git a/src/color-map.cpp b/src/color-map.cpp index a47d98c..d1d199a 100644 --- a/src/color-map.cpp +++ b/src/color-map.cpp @@ -124,6 +124,11 @@ InterpolationColorMap::Map(const RealWindow& input) const return output; } +std::unique_ptr<ColorMap> InterpolationColorMap::Copy() const +{ + return std::make_unique<InterpolationColorMap>(colors_, values_); +} + TwoColorMap::TwoColorMap(const sf::Color& c1, const sf::Color& c2) : InterpolationColorMap({ c1, c2 }, { 0.0f, 1.0f }) { diff --git a/src/color-map.hpp b/src/color-map.hpp index 4c89275..139edaf 100644 --- a/src/color-map.hpp +++ b/src/color-map.hpp @@ -44,6 +44,8 @@ public: virtual std::vector<uint8_t> Map(const RealWindow& input) const = 0; std::vector<uint8_t> Gradient(std::size_t width) const; + + virtual std::unique_ptr<ColorMap> Copy() const = 0; }; class InterpolationColorMap : public ColorMap { @@ -53,13 +55,12 @@ private: std::vector<uint8_t> GetColor(double value) const; -protected: - InterpolationColorMap(const std::vector<sf::Color>& colors, const std::vector<double>& vals); - public: + InterpolationColorMap(const std::vector<sf::Color>& colors, const std::vector<double>& vals); InterpolationColorMap() = delete; std::vector<uint8_t> Map(const std::vector<double>& input) const override; + std::unique_ptr<ColorMap> Copy() const override; }; class TwoColorMap : public InterpolationColorMap { diff --git a/src/live.cpp b/src/live.cpp index f1ae3d6..641eb7d 100644 --- a/src/live.cpp +++ b/src/live.cpp @@ -23,11 +23,17 @@ LiveOutput::LiveOutput(const Configuration& conf, const ColorMap& cmap, const Va /* FFT area raw memory used to update the area texture */ this->fft_area_.resize(conf.GetWidth() * conf.GetCount() * 4); /* RGBA pixel array */ + + /* render the live FFT area with a DC signal of zero */ + Render(); /* I don't have a good idea why this is needed, but I guess it has something to do with double buffering */ + this->renderer_.RenderFFTArea(this->fft_area_); + this->renderer_.RenderLiveFFT(RealWindow(conf.GetWidth())); } -void -LiveOutput::AddWindow(const std::vector<uint8_t>& window, const RealWindow& win_values) +std::vector<uint8_t> +LiveOutput::AddWindow(const RealWindow& win_values) { + auto window = this->renderer_.RenderLiveFFT(win_values); std::size_t wlen_bytes = this->configuration_.GetWidth() * 4; if (window.size() != wlen_bytes) { throw std::runtime_error("input window size differs from live window size"); @@ -43,12 +49,9 @@ LiveOutput::AddWindow(const std::vector<uint8_t>& window, const RealWindow& win_ reinterpret_cast<const void *>(window.data()), wlen_bytes); - /* update renderer */ + /* update renderer texture */ this->renderer_.RenderFFTArea(this->fft_area_); - this->renderer_.RenderLiveFFT(win_values, window); - - /* draw window */ - this->Render(); + return window; } bool @@ -65,6 +68,7 @@ LiveOutput::HandleEvents() void LiveOutput::Render() { + /* draw renderer output to window */ sf::Texture canvas_texture = this->renderer_.GetCanvas(); sf::Sprite canvas_sprite(canvas_texture); if (this->configuration_.IsHorizontal()) { @@ -74,4 +78,4 @@ LiveOutput::Render() this->window_.draw(canvas_sprite); this->window_.display(); -}
\ No newline at end of file +} diff --git a/src/live.hpp b/src/live.hpp index 5f6eb86..d7baa61 100644 --- a/src/live.hpp +++ b/src/live.hpp @@ -32,7 +32,7 @@ public: LiveOutput(const Configuration& conf, const ColorMap& cmap, const ValueMap& vmap); - void AddWindow(const std::vector<uint8_t>& window, const RealWindow& win_values); + std::vector<uint8_t> AddWindow(const RealWindow& win_values); bool HandleEvents(); void Render(); }; diff --git a/src/renderer.cpp b/src/renderer.cpp index 05fea43..e482bb0 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -38,8 +38,11 @@ ValueToShortString(double value, int prec, const std::string& unit) } Renderer::Renderer(const Configuration& conf, const ColorMap& cmap, const ValueMap& vmap, std::size_t fft_count) - : configuration_(conf), fft_count_(fft_count) + : configuration_(conf), fft_count_(fft_count), color_map_(cmap.Copy()) { + if (color_map_ == nullptr) { + throw std::runtime_error("failed to copy color map"); + } if (fft_count == 0) { throw std::runtime_error("positive number of FFT windows required by rendere"); } @@ -436,18 +439,18 @@ Renderer::RenderFFTArea(const std::list<std::vector<uint8_t>>& history) return this->RenderFFTArea(memory); } -void -Renderer::RenderLiveFFT(const RealWindow& window, const std::vector<uint8_t>& colors) +std::vector<uint8_t> +Renderer::RenderLiveFFT(const RealWindow& window) { if (window.size() != this->configuration_.GetWidth()) { throw std::runtime_error("incorrect window size to be rendered"); } - if (!this->configuration_.HasLiveWindow()) { - /* noop */ - return; + throw std::runtime_error("asked to render live window for non-live configuration"); } + std::vector<uint8_t> colors = this->color_map_->Map(window); + /* FFT live box (so we overwrite old one */ sf::RectangleShape fft_live_box(sf::Vector2f(this->configuration_.GetWidth(), this->configuration_.GetLiveFFTHeight() + 1.0f)); @@ -488,6 +491,7 @@ Renderer::RenderLiveFFT(const RealWindow& window, const std::vector<uint8_t>& co this->canvas_.draw(reinterpret_cast<sf::Vertex *>(vertices.data()), vertices.size(), sf::LineStrip, this->fft_live_transform_); + return colors; } sf::Texture diff --git a/src/renderer.hpp b/src/renderer.hpp index a473a2a..01ce397 100644 --- a/src/renderer.hpp +++ b/src/renderer.hpp @@ -30,6 +30,7 @@ class Renderer { private: const Configuration configuration_; const std::size_t fft_count_; + const std::unique_ptr<const ColorMap> color_map_; sf::Font font_; @@ -63,7 +64,7 @@ public: /* render commands */ void RenderFFTArea(const std::vector<uint8_t>& memory); void RenderFFTArea(const std::list<std::vector<uint8_t>>& history); - void RenderLiveFFT(const RealWindow& window, const std::vector<uint8_t>& colors); + std::vector<uint8_t> RenderLiveFFT(const RealWindow& window); /* canvas builder */ sf::Texture GetCanvas(); diff --git a/src/specgram.cpp b/src/specgram.cpp index cb646fc..d70126f 100644 --- a/src/specgram.cpp +++ b/src/specgram.cpp @@ -165,6 +165,7 @@ main(int argc, char** argv) std::unique_ptr<LiveOutput> live = nullptr; if (conf.IsLive()) { live = std::make_unique<LiveOutput>(conf, *color_map, *value_map); + live->Render(); /* render empty window */ } /* create input parser */ @@ -218,7 +219,7 @@ main(int argc, char** argv) /* main loop */ while (main_loop_running && !reader->ReachedEOF()) { - /* check for window events (if necessary) */ + /* check for window events (if necessary) and redraw */ if (live != nullptr) { if (!live->HandleEvents()) { /* exited by closing window */ @@ -226,6 +227,7 @@ main(int argc, char** argv) /* uninstall signal so that reader thread can exit successfully */ std::signal(SIGINT, nullptr); } + live->Render(); } /* check for a complete block */ @@ -282,7 +284,7 @@ main(int argc, char** argv) assert(window_sum.size() == normalized_magnitude.size()); assert(conf.GetAverageCount() > 0); for (std::size_t i = 0; i < window_sum.size(); i++) { - window_sum[i] += normalized_magnitude[i] / conf.GetAverageCount(); + window_sum[i] += normalized_magnitude[i] / (double)conf.GetAverageCount(); } window_sum_count++; @@ -291,17 +293,14 @@ main(int argc, char** argv) continue; } - /* colorize FFT */ - auto colorized = color_map->Map(window_sum); - /* add to live */ if (live != nullptr) { - live->AddWindow(colorized, window_sum); - } - - /* add to history */ - if (have_output) { - history.push_back(colorized); + auto colorized = live->AddWindow(window_sum); + if (have_output) { + history.push_back(colorized); + } + } else if (have_output) { + history.push_back(color_map->Map(window_sum)); } /* reset */ |
