]> git.sesse.net Git - nageru/blobdiff - nageru/audio_clip.cpp
Begin working on a delay analyzer.
[nageru] / nageru / audio_clip.cpp
diff --git a/nageru/audio_clip.cpp b/nageru/audio_clip.cpp
new file mode 100644 (file)
index 0000000..4dcb8db
--- /dev/null
@@ -0,0 +1,58 @@
+#include "audio_clip.h"
+
+#include <math.h>
+
+using namespace std;
+using namespace std::chrono;
+
+void AudioClip::clear()
+{
+       lock_guard<mutex> lock(mu);
+       vals.clear();
+}
+
+void AudioClip::add_audio(const float *samples, size_t num_samples, double sample_rate, std::chrono::steady_clock::time_point frame_time)
+{
+       lock_guard<mutex> lock(mu);
+       if (!vals.empty() && sample_rate != this->sample_rate) {
+               vals.clear();
+       }
+       if (vals.empty()) {
+               first_sample = frame_time;
+       }
+       this->sample_rate = sample_rate;
+       vals.insert(vals.end(), samples, samples + num_samples);
+}
+
+double AudioClip::get_length_seconds() const
+{
+       lock_guard<mutex> lock(mu);
+       if (vals.empty()) {
+               return 0.0;
+       }
+
+       return double(vals.size()) / sample_rate;
+}
+
+
+unique_ptr<pair<float, float>[]> AudioClip::get_min_max_peaks(unsigned width) const
+{
+       unique_ptr<pair<float, float>[]> min_max(new pair<float, float>[width]);
+       for (unsigned x = 0; x < width; ++x) {
+               min_max[x].first = min_max[x].second = 0.0 / 0.0;  // NaN.
+       }
+
+       lock_guard<mutex> lock(mu);
+       for (size_t i = 0; i < vals.size(); ++i) {
+               // We display one second.
+               int x = lrint(i * (double(width) / sample_rate));
+               if (x < 0 || x >= int(width)) continue;
+               if (isnan(min_max[x].first)) {
+                       min_max[x].first = min_max[x].second = 0.0;
+               }
+               min_max[x].first = min(min_max[x].first, vals[i]);
+               min_max[x].second = max(min_max[x].second, vals[i]);
+       }
+
+       return min_max;
+}