Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
decimation_resampler.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_audio/decimation_resampler.h
10 //! @brief Decimating resampler.
11 
12 #ifndef ROC_AUDIO_DECIMATION_RESAMPLER_H_
13 #define ROC_AUDIO_DECIMATION_RESAMPLER_H_
14 
15 #include "roc_audio/frame.h"
17 #include "roc_audio/iresampler.h"
18 #include "roc_audio/sample.h"
19 #include "roc_audio/sample_spec.h"
21 #include "roc_core/noncopyable.h"
22 #include "roc_core/rate_limiter.h"
23 #include "roc_core/slice.h"
24 #include "roc_core/stddefs.h"
25 
26 namespace roc {
27 namespace audio {
28 
29 //! Decimating resampler.
30 //!
31 //! Acts as decorator for another resampler instance.
32 //!
33 //! Performs resampling in two stages:
34 //! - first, uses underlying resampler to apply constant part of scaling factor based
35 //! on input and output rates; if these rates are equal, first stage is skipped
36 //! - then, uses decimation or duplication to apply dynamic part of scaling
37 //! factor, a.k.a. multiplier, by dropping or duplicating samples
38 //!
39 //! When input and output rates are the same, this backend implements fastest possible
40 //! resampling algorithm working almost at the speed of memcpy().
41 //!
42 //! Although decimation usually degrades quality a lot, it's not so dramatic in this
43 //! specific case because we use it only for dynamic part of scaling factor, which in
44 //! practice is very close to 1.0, and typically we remove or insert up to 20 samples
45 //! per second or so on 48kHz, which corresponds to ~ 0.4ms/second.
46 //!
47 //! When input and output rates are different, this backend uses another, underlying
48 //! resampler, but only for converting between input and output rates. It still uses
49 //! decimation or duplication for applying dynamic part of scaling factor.
51 public:
52  //! Initialize.
55  core::BufferFactory<sample_t>& buffer_factory,
56  const audio::SampleSpec& in_spec,
57  const audio::SampleSpec& out_spec);
58 
60 
61  //! Check if object is successfully constructed.
62  virtual bool is_valid() const;
63 
64  //! Set new resample factor.
65  virtual bool set_scaling(size_t input_rate, size_t output_rate, float multiplier);
66 
67  //! Get buffer to be filled with input data.
69 
70  //! Commit buffer with input data.
71  virtual void end_push_input();
72 
73  //! Read samples from input frame and fill output frame.
74  virtual size_t pop_output(sample_t* out_data, size_t out_size);
75 
76  //! How many samples were pushed but not processed yet.
77  virtual float n_left_to_process() const;
78 
79 private:
80  void report_stats_();
81 
82  const core::SharedPtr<IResampler> inner_resampler_;
83  bool use_inner_resampler_;
84 
85  audio::SampleSpec input_spec_;
86  audio::SampleSpec output_spec_;
87  float multiplier_;
88 
89  const size_t num_ch_;
90 
91  core::Slice<sample_t> in_buf_;
92  size_t in_size_;
93  size_t in_pos_;
94 
95  float out_acc_;
96 
97  core::Slice<sample_t> last_buf_;
98 
99  size_t total_count_;
100  size_t decim_count_;
101  core::RateLimiter report_limiter_;
102 
103  bool valid_;
104 };
105 
106 } // namespace audio
107 } // namespace roc
108 
109 #endif // ROC_AUDIO_DECIMATION_RESAMPLER_H_
Buffer factory.
virtual bool set_scaling(size_t input_rate, size_t output_rate, float multiplier)
Set new resample factor.
virtual void end_push_input()
Commit buffer with input data.
DecimationResampler(const core::SharedPtr< IResampler > &inner_resampler, core::IArena &arena, core::BufferFactory< sample_t > &buffer_factory, const audio::SampleSpec &in_spec, const audio::SampleSpec &out_spec)
Initialize.
virtual bool is_valid() const
Check if object is successfully constructed.
virtual size_t pop_output(sample_t *out_data, size_t out_size)
Read samples from input frame and fill output frame.
virtual const core::Slice< sample_t > & begin_push_input()
Get buffer to be filled with input data.
virtual float n_left_to_process() const
How many samples were pushed but not processed yet.
Audio writer interface.
Definition: iresampler.h:24
Sample specification. Describes sample rate and channels.
Definition: sample_spec.h:26
IArena & arena() const
Get arena.
Buffer factory. Allows to instantiate fixed-size buffers.
Memory arena interface.
Definition: iarena.h:23
Base class for non-copyable objects.
Definition: noncopyable.h:23
Shared ownership intrusive pointer.
Definition: shared_ptr.h:32
Audio frame.
Frame reader interface.
Audio resampler interface.
float sample_t
Audio sample.
Definition: sample.h:22
Root namespace.
Non-copyable object.
Rate limiter.
Audio sample.
Sample specifications.
Slice.
Commonly used types and functions.