1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
12 #define COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
13 
14 #include <memory>
15 
16 #include "common_audio/resampler/sinc_resampler.h"
17 #include "rtc_base/constructormagic.h"
18 #include "typedefs.h"  // NOLINT(build/include)
19 
20 namespace webrtc {
21 
22 // A thin wrapper over SincResampler to provide a push-based interface as
23 // required by WebRTC. SincResampler uses a pull-based interface, and will
24 // use SincResamplerCallback::Run() to request data upon a call to Resample().
25 // These Run() calls will happen on the same thread Resample() is called on.
26 class PushSincResampler : public SincResamplerCallback {
27  public:
28   // Provide the size of the source and destination blocks in samples. These
29   // must correspond to the same time duration (typically 10 ms) as the sample
30   // ratio is inferred from them.
31   PushSincResampler(size_t source_frames, size_t destination_frames);
32   ~PushSincResampler() override;
33 
34   // Perform the resampling. |source_frames| must always equal the
35   // |source_frames| provided at construction. |destination_capacity| must be
36   // at least as large as |destination_frames|. Returns the number of samples
37   // provided in destination (for convenience, since this will always be equal
38   // to |destination_frames|).
39   size_t Resample(const int16_t* source, size_t source_frames,
40                   int16_t* destination, size_t destination_capacity);
41   size_t Resample(const float* source,
42                   size_t source_frames,
43                   float* destination,
44                   size_t destination_capacity);
45 
46   // Delay due to the filter kernel. Essentially, the time after which an input
47   // sample will appear in the resampled output.
AlgorithmicDelaySeconds(int source_rate_hz)48   static float AlgorithmicDelaySeconds(int source_rate_hz) {
49     return 1.f / source_rate_hz * SincResampler::kKernelSize / 2;
50   }
51 
52  protected:
53   // Implements SincResamplerCallback.
54   void Run(size_t frames, float* destination) override;
55 
56  private:
57   friend class PushSincResamplerTest;
get_resampler_for_testing()58   SincResampler* get_resampler_for_testing() { return resampler_.get(); }
59 
60   std::unique_ptr<SincResampler> resampler_;
61   std::unique_ptr<float[]> float_buffer_;
62   const float* source_ptr_;
63   const int16_t* source_ptr_int_;
64   const size_t destination_frames_;
65 
66   // True on the first call to Resample(), to prime the SincResampler buffer.
67   bool first_pass_;
68 
69   // Used to assert we are only requested for as much data as is available.
70   size_t source_available_;
71 
72   RTC_DISALLOW_COPY_AND_ASSIGN(PushSincResampler);
73 };
74 
75 }  // namespace webrtc
76 
77 #endif  // COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
78