xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/merge.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef MODULES_AUDIO_CODING_NETEQ_MERGE_H_
12*d9f75844SAndroid Build Coastguard Worker #define MODULES_AUDIO_CODING_NETEQ_MERGE_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/neteq/audio_multi_vector.h"
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker // Forward declarations.
19*d9f75844SAndroid Build Coastguard Worker class Expand;
20*d9f75844SAndroid Build Coastguard Worker class SyncBuffer;
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker // This class handles the transition from expansion to normal operation.
23*d9f75844SAndroid Build Coastguard Worker // When a packet is not available for decoding when needed, the expand operation
24*d9f75844SAndroid Build Coastguard Worker // is called to generate extrapolation data. If the missing packet arrives,
25*d9f75844SAndroid Build Coastguard Worker // i.e., it was just delayed, it can be decoded and appended directly to the
26*d9f75844SAndroid Build Coastguard Worker // end of the expanded data (thanks to how the Expand class operates). However,
27*d9f75844SAndroid Build Coastguard Worker // if a later packet arrives instead, the loss is a fact, and the new data must
28*d9f75844SAndroid Build Coastguard Worker // be stitched together with the end of the expanded data. This stitching is
29*d9f75844SAndroid Build Coastguard Worker // what the Merge class does.
30*d9f75844SAndroid Build Coastguard Worker class Merge {
31*d9f75844SAndroid Build Coastguard Worker  public:
32*d9f75844SAndroid Build Coastguard Worker   Merge(int fs_hz,
33*d9f75844SAndroid Build Coastguard Worker         size_t num_channels,
34*d9f75844SAndroid Build Coastguard Worker         Expand* expand,
35*d9f75844SAndroid Build Coastguard Worker         SyncBuffer* sync_buffer);
36*d9f75844SAndroid Build Coastguard Worker   virtual ~Merge();
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker   Merge(const Merge&) = delete;
39*d9f75844SAndroid Build Coastguard Worker   Merge& operator=(const Merge&) = delete;
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker   // The main method to produce the audio data. The decoded data is supplied in
42*d9f75844SAndroid Build Coastguard Worker   // `input`, having `input_length` samples in total for all channels
43*d9f75844SAndroid Build Coastguard Worker   // (interleaved). The result is written to `output`. The number of channels
44*d9f75844SAndroid Build Coastguard Worker   // allocated in `output` defines the number of channels that will be used when
45*d9f75844SAndroid Build Coastguard Worker   // de-interleaving `input`.
46*d9f75844SAndroid Build Coastguard Worker   virtual size_t Process(int16_t* input,
47*d9f75844SAndroid Build Coastguard Worker                          size_t input_length,
48*d9f75844SAndroid Build Coastguard Worker                          AudioMultiVector* output);
49*d9f75844SAndroid Build Coastguard Worker 
50*d9f75844SAndroid Build Coastguard Worker   virtual size_t RequiredFutureSamples();
51*d9f75844SAndroid Build Coastguard Worker 
52*d9f75844SAndroid Build Coastguard Worker  protected:
53*d9f75844SAndroid Build Coastguard Worker   const int fs_hz_;
54*d9f75844SAndroid Build Coastguard Worker   const size_t num_channels_;
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker  private:
57*d9f75844SAndroid Build Coastguard Worker   static const int kMaxSampleRate = 48000;
58*d9f75844SAndroid Build Coastguard Worker   static const size_t kExpandDownsampLength = 100;
59*d9f75844SAndroid Build Coastguard Worker   static const size_t kInputDownsampLength = 40;
60*d9f75844SAndroid Build Coastguard Worker   static const size_t kMaxCorrelationLength = 60;
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker   // Calls `expand_` to get more expansion data to merge with. The data is
63*d9f75844SAndroid Build Coastguard Worker   // written to `expanded_signal_`. Returns the length of the expanded data,
64*d9f75844SAndroid Build Coastguard Worker   // while `expand_period` will be the number of samples in one expansion period
65*d9f75844SAndroid Build Coastguard Worker   // (typically one pitch period). The value of `old_length` will be the number
66*d9f75844SAndroid Build Coastguard Worker   // of samples that were taken from the `sync_buffer_`.
67*d9f75844SAndroid Build Coastguard Worker   size_t GetExpandedSignal(size_t* old_length, size_t* expand_period);
68*d9f75844SAndroid Build Coastguard Worker 
69*d9f75844SAndroid Build Coastguard Worker   // Analyzes `input` and `expanded_signal` and returns muting factor (Q14) to
70*d9f75844SAndroid Build Coastguard Worker   // be used on the new data.
71*d9f75844SAndroid Build Coastguard Worker   int16_t SignalScaling(const int16_t* input,
72*d9f75844SAndroid Build Coastguard Worker                         size_t input_length,
73*d9f75844SAndroid Build Coastguard Worker                         const int16_t* expanded_signal) const;
74*d9f75844SAndroid Build Coastguard Worker 
75*d9f75844SAndroid Build Coastguard Worker   // Downsamples `input` (`input_length` samples) and `expanded_signal` to
76*d9f75844SAndroid Build Coastguard Worker   // 4 kHz sample rate. The downsampled signals are written to
77*d9f75844SAndroid Build Coastguard Worker   // `input_downsampled_` and `expanded_downsampled_`, respectively.
78*d9f75844SAndroid Build Coastguard Worker   void Downsample(const int16_t* input,
79*d9f75844SAndroid Build Coastguard Worker                   size_t input_length,
80*d9f75844SAndroid Build Coastguard Worker                   const int16_t* expanded_signal,
81*d9f75844SAndroid Build Coastguard Worker                   size_t expanded_length);
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   // Calculates cross-correlation between `input_downsampled_` and
84*d9f75844SAndroid Build Coastguard Worker   // `expanded_downsampled_`, and finds the correlation maximum. The maximizing
85*d9f75844SAndroid Build Coastguard Worker   // lag is returned.
86*d9f75844SAndroid Build Coastguard Worker   size_t CorrelateAndPeakSearch(size_t start_position,
87*d9f75844SAndroid Build Coastguard Worker                                 size_t input_length,
88*d9f75844SAndroid Build Coastguard Worker                                 size_t expand_period) const;
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker   const int fs_mult_;  // fs_hz_ / 8000.
91*d9f75844SAndroid Build Coastguard Worker   const size_t timestamps_per_call_;
92*d9f75844SAndroid Build Coastguard Worker   Expand* expand_;
93*d9f75844SAndroid Build Coastguard Worker   SyncBuffer* sync_buffer_;
94*d9f75844SAndroid Build Coastguard Worker   int16_t expanded_downsampled_[kExpandDownsampLength];
95*d9f75844SAndroid Build Coastguard Worker   int16_t input_downsampled_[kInputDownsampLength];
96*d9f75844SAndroid Build Coastguard Worker   AudioMultiVector expanded_;
97*d9f75844SAndroid Build Coastguard Worker   std::vector<int16_t> temp_data_;
98*d9f75844SAndroid Build Coastguard Worker };
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
101*d9f75844SAndroid Build Coastguard Worker #endif  // MODULES_AUDIO_CODING_NETEQ_MERGE_H_
102