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 MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_DETECTOR_H_
12 #define MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_DETECTOR_H_
13 
14 #include <deque>
15 #include <memory>
16 
17 #include "modules/audio_processing/transient/moving_moments.h"
18 #include "modules/audio_processing/transient/wpd_tree.h"
19 
20 namespace webrtc {
21 
22 // This is an implementation of the transient detector described in "Causal
23 // Wavelet based transient detector".
24 // Calculates the log-likelihood of a transient to happen on a signal at any
25 // given time based on the previous samples; it uses a WPD tree to analyze the
26 // signal.  It preserves its state, so it can be multiple-called.
27 class TransientDetector {
28  public:
29   // TODO(chadan): The only supported wavelet is Daubechies 8 using a WPD tree
30   // of 3 levels. Make an overloaded constructor to allow different wavelets and
31   // depths of the tree. When needed.
32 
33   // Creates a wavelet based transient detector.
34   TransientDetector(int sample_rate_hz);
35 
36   ~TransientDetector();
37 
38   // Calculates the log-likelihood of the existence of a transient in |data|.
39   // |data_length| has to be equal to |samples_per_chunk_|.
40   // Returns a value between 0 and 1, as a non linear representation of this
41   // likelihood.
42   // Returns a negative value on error.
43   float Detect(const float* data,
44                size_t data_length,
45                const float* reference_data,
46                size_t reference_length);
47 
using_reference()48   bool using_reference() { return using_reference_; }
49 
50  private:
51   float ReferenceDetectionValue(const float* data, size_t length);
52 
53   static const size_t kLevels = 3;
54   static const size_t kLeaves = 1 << kLevels;
55 
56   size_t samples_per_chunk_;
57 
58   std::unique_ptr<WPDTree> wpd_tree_;
59   size_t tree_leaves_data_length_;
60 
61   // A MovingMoments object is needed for each leaf in the WPD tree.
62   std::unique_ptr<MovingMoments> moving_moments_[kLeaves];
63 
64   std::unique_ptr<float[]> first_moments_;
65   std::unique_ptr<float[]> second_moments_;
66 
67   // Stores the last calculated moments from the previous detection.
68   float last_first_moment_[kLeaves];
69   float last_second_moment_[kLeaves];
70 
71   // We keep track of the previous results from the previous chunks, so it can
72   // be used to effectively give results according to the |transient_length|.
73   std::deque<float> previous_results_;
74 
75   // Number of chunks that are going to return only zeros at the beginning of
76   // the detection. It helps to avoid infs and nans due to the lack of
77   // information.
78   int chunks_at_startup_left_to_delete_;
79 
80   float reference_energy_;
81 
82   bool using_reference_;
83 };
84 
85 }  // namespace webrtc
86 
87 #endif  // MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_DETECTOR_H_
88