mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00

Bug: webrtc:12338 Change-Id: I85bff694dd2ead83c939c4d1945eff82e1296001 No-Presubmit: True Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227161 Commit-Queue: Artem Titov <titovartem@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34690}
95 lines
3.8 KiB
C++
95 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_SYMMETRIC_MATRIX_BUFFER_H_
|
|
#define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_SYMMETRIC_MATRIX_BUFFER_H_
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cstring>
|
|
#include <utility>
|
|
|
|
#include "api/array_view.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/numerics/safe_compare.h"
|
|
|
|
namespace webrtc {
|
|
namespace rnn_vad {
|
|
|
|
// Data structure to buffer the results of pair-wise comparisons between items
|
|
// stored in a ring buffer. Every time that the oldest item is replaced in the
|
|
// ring buffer, the new one is compared to the remaining items in the ring
|
|
// buffer. The results of such comparisons need to be buffered and automatically
|
|
// removed when one of the two corresponding items that have been compared is
|
|
// removed from the ring buffer. It is assumed that the comparison is symmetric
|
|
// and that comparing an item with itself is not needed.
|
|
template <typename T, int S>
|
|
class SymmetricMatrixBuffer {
|
|
static_assert(S > 2, "");
|
|
|
|
public:
|
|
SymmetricMatrixBuffer() = default;
|
|
SymmetricMatrixBuffer(const SymmetricMatrixBuffer&) = delete;
|
|
SymmetricMatrixBuffer& operator=(const SymmetricMatrixBuffer&) = delete;
|
|
~SymmetricMatrixBuffer() = default;
|
|
// Sets the buffer values to zero.
|
|
void Reset() {
|
|
static_assert(std::is_arithmetic<T>::value,
|
|
"Integral or floating point required.");
|
|
buf_.fill(0);
|
|
}
|
|
// Pushes the results from the comparison between the most recent item and
|
|
// those that are still in the ring buffer. The first element in `values` must
|
|
// correspond to the comparison between the most recent item and the second
|
|
// most recent one in the ring buffer, whereas the last element in `values`
|
|
// must correspond to the comparison between the most recent item and the
|
|
// oldest one in the ring buffer.
|
|
void Push(rtc::ArrayView<T, S - 1> values) {
|
|
// Move the lower-right sub-matrix of size (S-2) x (S-2) one row up and one
|
|
// column left.
|
|
std::memmove(buf_.data(), buf_.data() + S, (buf_.size() - S) * sizeof(T));
|
|
// Copy new values in the last column in the right order.
|
|
for (int i = 0; rtc::SafeLt(i, values.size()); ++i) {
|
|
const int index = (S - 1 - i) * (S - 1) - 1;
|
|
RTC_DCHECK_GE(index, 0);
|
|
RTC_DCHECK_LT(index, buf_.size());
|
|
buf_[index] = values[i];
|
|
}
|
|
}
|
|
// Reads the value that corresponds to comparison of two items in the ring
|
|
// buffer having delay `delay1` and `delay2`. The two arguments must not be
|
|
// equal and both must be in {0, ..., S - 1}.
|
|
T GetValue(int delay1, int delay2) const {
|
|
int row = S - 1 - delay1;
|
|
int col = S - 1 - delay2;
|
|
RTC_DCHECK_NE(row, col) << "The diagonal cannot be accessed.";
|
|
if (row > col)
|
|
std::swap(row, col); // Swap to access the upper-right triangular part.
|
|
RTC_DCHECK_LE(0, row);
|
|
RTC_DCHECK_LT(row, S - 1) << "Not enforcing row < col and row != col.";
|
|
RTC_DCHECK_LE(1, col) << "Not enforcing row < col and row != col.";
|
|
RTC_DCHECK_LT(col, S);
|
|
const int index = row * (S - 1) + (col - 1);
|
|
RTC_DCHECK_LE(0, index);
|
|
RTC_DCHECK_LT(index, buf_.size());
|
|
return buf_[index];
|
|
}
|
|
|
|
private:
|
|
// Encode an upper-right triangular matrix (excluding its diagonal) using a
|
|
// square matrix. This allows to move the data in Push() with one single
|
|
// operation.
|
|
std::array<T, (S - 1) * (S - 1)> buf_{};
|
|
};
|
|
|
|
} // namespace rnn_vad
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_SYMMETRIC_MATRIX_BUFFER_H_
|