Ardour  9.8-201-g363d29fd54
lufs_meter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2026 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 #ifndef _lufs_meter_h_
19 #define _lufs_meter_h_
20 
21 #include <atomic>
22 #include <cstdint>
23 #include <functional>
24 #include <map>
25 
26 #include "pbd/stack_allocator.h"
27 #include "pbd/ringbuffer.h"
28 
30 
31 namespace ARDOUR {
32 
34 {
35 public:
36  LUFSMeter (double samplerate, uint32_t n_channels, bool with_hist = false);
37  LUFSMeter (LUFSMeter const& other) = delete;
39 
40  void run (float const** data, uint32_t n_samples);
41  void reset ();
42 
43  float integrated_loudness () const;
44  float momentary () const;
45  float max_momentary () const;
46  float short_term () const;
47  float max_short_term () const;
48  float lu_range () const;
49  void lu_range_min_max (float& range_min, float& range_max) const;
50  float dbtp ();
51  float max_dbtp () const;
52 
53  struct LUHistory {
54  float integrated;
55  float short_term;
56  float momentary;
57  };
58 
59  size_t hist_read (LUHistory* dest, size_t cnt) {
60  return _rb.read (dest, cnt);
61  }
62 
63  size_t hist_read_space () const {
64  return _rb.read_space ();
65  }
66 
67  void host_increment_read_idx (size_t cnt) {
68  _rb.increment_read_idx (cnt);
69  }
70 
71 private:
72  void init ();
73  void clear ();
74 
75  float process (float const** data, const uint32_t n_samples, uint32_t offset);
76  float sumfrag (uint32_t) const;
77 
78  void calc_true_peak (float const** data, const uint32_t n_samples);
79  float upsample_x4 (int chn, float const x);
80  float upsample_x2 (int chn, float const x);
81 
82  std::function< float(int, const float) > upsample;
83 
84  const float _g[5] = { 1.0, 1.0, 1.0, 1.41, 1.41 };
85 
86  /* config */
87  double _samplerate;
88  uint32_t _n_channels;
89  uint32_t _n_fragment;
90 
91  /* filter coeff */
92  float _a0, _a1, _a2;
93  float _b1, _b2;
94  float _c3, _c4;
95 
96  /* state */
97  uint32_t _frag_pos;
98  float _frag_pwr;
99  uint32_t _block_cnt;
100  float _block_pwr;
101  float _power[32];
102  uint32_t _pow_idx;
103  float _thresh_rel;
104  uint32_t _lu_s_div;
105 
107  float _short_l;
108 
109  float _range_min;
110  float _range_max;
111 
112  float _maxloudn_M;
113  float _maxloudn_S;
114  float _integrated;
115  float _dbtp;
116  float _max_dbtp;
117 
118  std::atomic<bool> _rst_dbtp;
119  std::atomic<bool> _rst_lufs;
120 
121 #if defined(_MSC_VER)
122  typedef std::map<int, uint32_t> History;
123 #else
124  typedef std::map<int, uint32_t, std::less<int>, PBD::StackAllocator<std::pair<const int, uint32_t>, 1000>> History;
125 #endif
126 
129 
130  std::map<int, float> power_table;
131 
132  struct FilterState {
133  void reset ();
134  void sanitize ();
135 
136  float z1, z2, z3, z4;
137  };
138 
139  FilterState _fst[5];
140  float* _z[5];
141 
143 
145 };
146 
147 } // namespace ARDOUR
148 #endif
float integrated_loudness() const
uint32_t _n_channels
Definition: lufs_meter.h:88
float max_dbtp() const
uint32_t _n_fragment
Definition: lufs_meter.h:89
std::atomic< bool > _rst_dbtp
Definition: lufs_meter.h:118
size_t hist_read(LUHistory *dest, size_t cnt)
Definition: lufs_meter.h:59
PBD::RingBuffer< LUHistory > _rb
Definition: lufs_meter.h:144
float process(float const **data, const uint32_t n_samples, uint32_t offset)
void host_increment_read_idx(size_t cnt)
Definition: lufs_meter.h:67
uint32_t _lu_s_div
Definition: lufs_meter.h:104
float short_term() const
float max_momentary() const
void calc_true_peak(float const **data, const uint32_t n_samples)
double _samplerate
Definition: lufs_meter.h:87
uint32_t _frag_pos
Definition: lufs_meter.h:97
float max_short_term() const
float upsample_x2(int chn, float const x)
float momentary() const
void lu_range_min_max(float &range_min, float &range_max) const
size_t hist_read_space() const
Definition: lufs_meter.h:63
LUFSMeter(double samplerate, uint32_t n_channels, bool with_hist=false)
std::map< int, uint32_t, std::less< int >, PBD::StackAllocator< std::pair< const int, uint32_t >, 1000 > > History
Definition: lufs_meter.h:124
LUFSMeter(LUFSMeter const &other)=delete
float sumfrag(uint32_t) const
std::map< int, float > power_table
Definition: lufs_meter.h:130
uint32_t _block_cnt
Definition: lufs_meter.h:99
uint32_t _pow_idx
Definition: lufs_meter.h:102
std::atomic< bool > _rst_lufs
Definition: lufs_meter.h:119
float lu_range() const
float upsample_x4(int chn, float const x)
void run(float const **data, uint32_t n_samples)
std::function< float(int, const float) > upsample
Definition: lufs_meter.h:82
#define LIBARDOUR_API