1 #include "audio_clip.h"
7 using namespace std::chrono;
9 void AudioClip::clear()
11 lock_guard<mutex> lock(mu);
15 void AudioClip::add_audio(const float *samples, size_t num_samples, double sample_rate, std::chrono::steady_clock::time_point frame_time)
17 lock_guard<mutex> lock(mu);
18 if (!vals.empty() && sample_rate != this->sample_rate) {
22 first_sample = frame_time;
24 this->sample_rate = sample_rate;
25 vals.insert(vals.end(), samples, samples + num_samples);
28 double AudioClip::get_length_seconds() const
30 lock_guard<mutex> lock(mu);
35 return double(vals.size()) / sample_rate;
38 double AudioClip::get_length_seconds_after_base(std::chrono::steady_clock::time_point base) const
40 lock_guard<mutex> lock(mu);
41 if (vals.empty() || base < first_sample) {
42 // NOTE: base < first_sample can happen only during race conditions.
46 return double(vals.size()) / sample_rate - duration<double>(base - first_sample).count();
49 bool AudioClip::empty() const
51 lock_guard<mutex> lock(mu);
55 steady_clock::time_point AudioClip::get_first_sample() const
57 lock_guard<mutex> lock(mu);
58 assert(!vals.empty());
62 unique_ptr<pair<float, float>[]> AudioClip::get_min_max_peaks(unsigned width, steady_clock::time_point base) const
64 unique_ptr<pair<float, float>[]> min_max(new pair<float, float>[width]);
65 for (unsigned x = 0; x < width; ++x) {
66 min_max[x].first = min_max[x].second = 0.0 / 0.0; // NaN.
69 lock_guard<mutex> lock(mu);
70 double skip_samples = duration<double>(base - first_sample).count() * sample_rate;
71 for (size_t i = int(floor(skip_samples)); i < vals.size(); ++i) {
72 // We display one second.
73 int x = lrint((i - skip_samples) * (double(width) / sample_rate));
74 if (x < 0 || x >= int(width)) continue;
75 if (isnan(min_max[x].first)) {
76 min_max[x].first = min_max[x].second = 0.0;
78 min_max[x].first = min(min_max[x].first, vals[i]);
79 min_max[x].second = max(min_max[x].second, vals[i]);