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