summaryrefslogtreecommitdiffstats
path: root/src/spectro_source.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/spectro_source.hh')
-rw-r--r--src/spectro_source.hh208
1 files changed, 208 insertions, 0 deletions
diff --git a/src/spectro_source.hh b/src/spectro_source.hh
new file mode 100644
index 0000000..c337ef1
--- /dev/null
+++ b/src/spectro_source.hh
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2016, Timothy Stack
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Timothy Stack nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @file spectroview_curses.hh
+ */
+
+#ifndef spectro_source_hh
+#define spectro_source_hh
+
+#include <unordered_map>
+#include <vector>
+
+#include <math.h>
+#include <time.h>
+
+#include "statusview_curses.hh"
+#include "textview_curses.hh"
+
+struct exec_context;
+
+struct spectrogram_bounds {
+ time_t sb_begin_time{0};
+ time_t sb_end_time{0};
+ double sb_min_value_out{0.0};
+ double sb_max_value_out{0.0};
+ int64_t sb_count{0};
+};
+
+struct spectrogram_thresholds {
+ int st_green_threshold{0};
+ int st_yellow_threshold{0};
+};
+
+struct spectrogram_request {
+ explicit spectrogram_request(spectrogram_bounds& sb) : sr_bounds(sb) {}
+
+ spectrogram_bounds& sr_bounds;
+ unsigned long sr_width{0};
+ time_t sr_begin_time{0};
+ time_t sr_end_time{0};
+ double sr_column_size{0};
+};
+
+struct spectrogram_row {
+ spectrogram_row() = default;
+ spectrogram_row(const spectrogram_row&) = delete;
+
+ struct row_bucket {
+ int rb_counter{0};
+ int rb_marks{0};
+ };
+
+ std::vector<row_bucket> sr_values;
+ unsigned long sr_width{0};
+ double sr_column_size{0.0};
+ std::function<std::unique_ptr<text_sub_source>(
+ const spectrogram_request&, double range_min, double range_max)>
+ sr_details_source_provider;
+
+ void add_value(spectrogram_request& sr, double value, bool marked)
+ {
+ long index = std::floor((value - sr.sr_bounds.sb_min_value_out)
+ / sr.sr_column_size);
+
+ this->sr_values[index].rb_counter += 1;
+ if (marked) {
+ this->sr_values[index].rb_marks += 1;
+ }
+ }
+
+ nonstd::optional<size_t> nearest_column(size_t current) const;
+};
+
+class spectrogram_value_source {
+public:
+ virtual ~spectrogram_value_source() = default;
+
+ virtual void spectro_bounds(spectrogram_bounds& sb_out) = 0;
+
+ virtual void spectro_row(spectrogram_request& sr, spectrogram_row& row_out)
+ = 0;
+
+ virtual void spectro_mark(textview_curses& tc,
+ time_t begin_time,
+ time_t end_time,
+ double range_min,
+ double range_max)
+ = 0;
+};
+
+class spectrogram_source
+ : public text_sub_source
+ , public text_time_translator
+ , public list_overlay_source
+ , public list_input_delegate {
+public:
+ ~spectrogram_source() override = default;
+
+ void invalidate()
+ {
+ this->ss_cached_bounds.sb_count = 0;
+ this->ss_row_cache.clear();
+ this->ss_cursor_column = nonstd::nullopt;
+ }
+
+ bool list_input_handle_key(listview_curses& lv, int ch) override;
+
+ bool list_value_for_overlay(const listview_curses& lv,
+ int y,
+ int bottom,
+ vis_line_t row,
+ attr_line_t& value_out) override;
+
+ size_t text_line_count() override;
+
+ size_t text_line_width(textview_curses& tc) override;
+
+ size_t text_size_for_line(textview_curses& tc,
+ int row,
+ line_flags_t flags) override
+ {
+ return 0;
+ }
+
+ bool text_is_row_selectable(textview_curses& tc, vis_line_t row) override;
+
+ void text_selection_changed(textview_curses& tc) override;
+
+ nonstd::optional<struct timeval> time_for_row(vis_line_t row) override;
+
+ nonstd::optional<vis_line_t> row_for_time(
+ struct timeval time_bucket) override;
+
+ void text_value_for_line(textview_curses& tc,
+ int row,
+ std::string& value_out,
+ line_flags_t flags) override;
+
+ void text_attrs_for_line(textview_curses& tc,
+ int row,
+ string_attrs_t& value_out) override;
+
+ void cache_bounds();
+
+ nonstd::optional<struct timeval> time_for_row_int(vis_line_t row);
+
+ const spectrogram_row& load_row(const listview_curses& lv, int row);
+
+ void reset_details_source();
+
+ textview_curses* ss_details_view;
+ text_sub_source* ss_no_details_source;
+ exec_context* ss_exec_context;
+ std::unique_ptr<text_sub_source> ss_details_source;
+ int ss_granularity{60};
+ spectrogram_value_source* ss_value_source{nullptr};
+ spectrogram_bounds ss_cached_bounds;
+ spectrogram_thresholds ss_cached_thresholds;
+ size_t ss_cached_line_count{0};
+ std::unordered_map<time_t, spectrogram_row> ss_row_cache;
+ nonstd::optional<size_t> ss_cursor_column;
+};
+
+class spectro_status_source : public status_data_source {
+public:
+ enum field_t {
+ F_TITLE,
+ F_HELP,
+
+ F_MAX
+ };
+
+ spectro_status_source();
+
+ size_t statusview_fields() override;
+
+ status_field& statusview_value_for_field(int field) override;
+
+private:
+ status_field sss_fields[F_MAX];
+};
+
+#endif