]> git.sesse.net Git - nageru/blob - nageru/audio_clip.cpp
Begin working on a delay analyzer.
[nageru] / nageru / audio_clip.cpp
1 #include "audio_clip.h"
2
3 #include <math.h>
4
5 using namespace std;
6 using namespace std::chrono;
7
8 void AudioClip::clear()
9 {
10         lock_guard<mutex> lock(mu);
11         vals.clear();
12 }
13
14 void AudioClip::add_audio(const float *samples, size_t num_samples, double sample_rate, std::chrono::steady_clock::time_point frame_time)
15 {
16         lock_guard<mutex> lock(mu);
17         if (!vals.empty() && sample_rate != this->sample_rate) {
18                 vals.clear();
19         }
20         if (vals.empty()) {
21                 first_sample = frame_time;
22         }
23         this->sample_rate = sample_rate;
24         vals.insert(vals.end(), samples, samples + num_samples);
25 }
26
27 double AudioClip::get_length_seconds() const
28 {
29         lock_guard<mutex> lock(mu);
30         if (vals.empty()) {
31                 return 0.0;
32         }
33
34         return double(vals.size()) / sample_rate;
35 }
36
37
38 unique_ptr<pair<float, float>[]> AudioClip::get_min_max_peaks(unsigned width) const
39 {
40         unique_ptr<pair<float, float>[]> min_max(new pair<float, float>[width]);
41         for (unsigned x = 0; x < width; ++x) {
42                 min_max[x].first = min_max[x].second = 0.0 / 0.0;  // NaN.
43         }
44
45         lock_guard<mutex> lock(mu);
46         for (size_t i = 0; i < vals.size(); ++i) {
47                 // We display one second.
48                 int x = lrint(i * (double(width) / sample_rate));
49                 if (x < 0 || x >= int(width)) continue;
50                 if (isnan(min_max[x].first)) {
51                         min_max[x].first = min_max[x].second = 0.0;
52                 }
53                 min_max[x].first = min(min_max[x].first, vals[i]);
54                 min_max[x].second = max(min_max[x].second, vals[i]);
55         }
56
57         return min_max;
58 }