Home | History | Annotate | Download | only in neteq
      1 /*
      2  *  Copyright (c) 2012 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 #include "webrtc/modules/audio_coding/neteq/accelerate.h"
     12 
     13 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     14 
     15 namespace webrtc {
     16 
     17 Accelerate::ReturnCodes Accelerate::Process(
     18     const int16_t* input,
     19     size_t input_length,
     20     AudioMultiVector* output,
     21     int16_t* length_change_samples) {
     22   // Input length must be (almost) 30 ms.
     23   static const int k15ms = 120;  // 15 ms = 120 samples at 8 kHz sample rate.
     24   if (num_channels_ == 0 || static_cast<int>(input_length) / num_channels_ <
     25       (2 * k15ms - 1) * fs_mult_) {
     26     // Length of input data too short to do accelerate. Simply move all data
     27     // from input to output.
     28     output->PushBackInterleaved(input, input_length);
     29     return kError;
     30   }
     31   return TimeStretch::Process(input, input_length, output,
     32                               length_change_samples);
     33 }
     34 
     35 void Accelerate::SetParametersForPassiveSpeech(size_t /*len*/,
     36                                                int16_t* best_correlation,
     37                                                int* /*peak_index*/) const {
     38   // When the signal does not contain any active speech, the correlation does
     39   // not matter. Simply set it to zero.
     40   *best_correlation = 0;
     41 }
     42 
     43 Accelerate::ReturnCodes Accelerate::CheckCriteriaAndStretch(
     44     const int16_t* input, size_t input_length, size_t peak_index,
     45     int16_t best_correlation, bool active_speech,
     46     AudioMultiVector* output) const {
     47   // Check for strong correlation or passive speech.
     48   if ((best_correlation > kCorrelationThreshold) || !active_speech) {
     49     // Do accelerate operation by overlap add.
     50 
     51     // Pre-calculate common multiplication with |fs_mult_|.
     52     // 120 corresponds to 15 ms.
     53     size_t fs_mult_120 = fs_mult_ * 120;
     54 
     55     assert(fs_mult_120 >= peak_index);  // Should be handled in Process().
     56     // Copy first part; 0 to 15 ms.
     57     output->PushBackInterleaved(input, fs_mult_120 * num_channels_);
     58     // Copy the |peak_index| starting at 15 ms to |temp_vector|.
     59     AudioMultiVector temp_vector(num_channels_);
     60     temp_vector.PushBackInterleaved(&input[fs_mult_120 * num_channels_],
     61                                     peak_index * num_channels_);
     62     // Cross-fade |temp_vector| onto the end of |output|.
     63     output->CrossFade(temp_vector, peak_index);
     64     // Copy the last unmodified part, 15 ms + pitch period until the end.
     65     output->PushBackInterleaved(
     66         &input[(fs_mult_120 + peak_index) * num_channels_],
     67         input_length - (fs_mult_120 + peak_index) * num_channels_);
     68 
     69     if (active_speech) {
     70       return kSuccess;
     71     } else {
     72       return kSuccessLowEnergy;
     73     }
     74   } else {
     75     // Accelerate not allowed. Simply move all data from decoded to outData.
     76     output->PushBackInterleaved(input, input_length);
     77     return kNoStretch;
     78   }
     79 }
     80 
     81 Accelerate* AccelerateFactory::Create(
     82     int sample_rate_hz,
     83     size_t num_channels,
     84     const BackgroundNoise& background_noise) const {
     85   return new Accelerate(sample_rate_hz, num_channels, background_noise);
     86 }
     87 
     88 }  // namespace webrtc
     89