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_WPD_TREE_H_
12 #define MODULES_AUDIO_PROCESSING_TRANSIENT_WPD_TREE_H_
13 
14 #include <stddef.h>
15 
16 #include <memory>
17 
18 #include "modules/audio_processing/transient/wpd_node.h"
19 
20 namespace webrtc {
21 
22 // Tree of a Wavelet Packet Decomposition (WPD).
23 //
24 // The root node contains all the data provided; for each node in the tree, the
25 // left child contains the approximation coefficients extracted from the node,
26 // and the right child contains the detail coefficients.
27 // It preserves its state, so it can be multiple-called.
28 //
29 // The number of nodes in the tree will be 2 ^ levels - 1.
30 //
31 // Implementation details: Since the tree always will be a complete binary tree,
32 // it is implemented using a single linear array instead of managing the
33 // relationships in each node. For convience is better to use a array that
34 // starts in 1 (instead of 0). Taking that into account, the following formulas
35 // apply:
36 // Root node index: 1.
37 // Node(Level, Index in that level): 2 ^ Level + (Index in that level).
38 // Left Child: Current node index * 2.
39 // Right Child: Current node index * 2 + 1.
40 // Parent: Current Node Index / 2 (Integer division).
41 class WPDTree {
42  public:
43   // Creates a WPD tree using the data length and coefficients provided.
44   WPDTree(size_t data_length,
45           const float* high_pass_coefficients,
46           const float* low_pass_coefficients,
47           size_t coefficients_length,
48           int levels);
49   ~WPDTree();
50 
51   // Returns the number of nodes at any given level.
NumberOfNodesAtLevel(int level)52   static int NumberOfNodesAtLevel(int level) { return 1 << level; }
53 
54   // Returns a pointer to the node at the given level and index(of that level).
55   // Level goes from 0 to levels().
56   // Index goes from 0 to the number of NumberOfNodesAtLevel(level) - 1.
57   //
58   // You can use the following formulas to get any node within the tree:
59   // Notation: (Level, Index of node in that level).
60   // Root node: (0/0).
61   // Left Child: (Current node level + 1, Current node index * 2).
62   // Right Child: (Current node level + 1, Current node index * 2 + 1).
63   // Parent: (Current node level - 1, Current node index / 2) (Integer division)
64   //
65   // If level or index are out of bounds the function will return NULL.
66   WPDNode* NodeAt(int level, int index);
67 
68   // Updates all the nodes of the tree with the new data. |data_length| must be
69   // teh same that was used for the creation of the tree.
70   // Returns 0 if correct, and -1 otherwise.
71   int Update(const float* data, size_t data_length);
72 
73   // Returns the total number of levels below the root. Root is cosidered level
74   // 0.
levels()75   int levels() const { return levels_; }
76 
77   // Returns the total number of nodes.
num_nodes()78   int num_nodes() const { return num_nodes_; }
79 
80   // Returns the total number of leaves.
num_leaves()81   int num_leaves() const { return 1 << levels_; }
82 
83  private:
84   size_t data_length_;
85   int levels_;
86   int num_nodes_;
87   std::unique_ptr<std::unique_ptr<WPDNode>[]> nodes_;
88 };
89 
90 }  // namespace webrtc
91 
92 #endif  // MODULES_AUDIO_PROCESSING_TRANSIENT_WPD_TREE_H_
93