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