tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_view_unittest.cc (6950B)


      1 /*
      2 *  Copyright 2024 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 "api/audio/audio_view.h"
     12 
     13 #include <array>
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <vector>
     17 
     18 #include "api/array_view.h"
     19 #include "test/gtest.h"
     20 
     21 namespace webrtc {
     22 
     23 namespace {
     24 
     25 constexpr const float kFloatStepIncrease = 0.5f;
     26 constexpr const int16_t kIntStepIncrease = 1;
     27 
     28 template <typename T>
     29 void Increment(float& t) {
     30  t += kFloatStepIncrease;
     31 }
     32 
     33 template <typename T>
     34 void Increment(int16_t& t) {
     35  t += kIntStepIncrease;
     36 }
     37 
     38 // Fills a given buffer with monotonically increasing values.
     39 template <typename T>
     40 void FillBuffer(ArrayView<T> buffer) {
     41  T value = {};
     42  for (T& t : buffer) {
     43    Increment<T>(value);
     44    t = value;
     45  }
     46 }
     47 
     48 }  // namespace
     49 
     50 TEST(AudioViewTest, MonoView) {
     51  const size_t kArraySize = 100u;
     52  int16_t arr[kArraySize];
     53  FillBuffer(ArrayView<int16_t>(arr));
     54 
     55  MonoView<int16_t> mono(arr);
     56  MonoView<const int16_t> const_mono(arr);
     57  EXPECT_EQ(mono.size(), kArraySize);
     58  EXPECT_EQ(const_mono.size(), kArraySize);
     59  EXPECT_EQ(&mono[0], &const_mono[0]);
     60  EXPECT_EQ(mono[0], arr[0]);
     61 
     62  EXPECT_EQ(1u, NumChannels(mono));
     63  EXPECT_EQ(1u, NumChannels(const_mono));
     64  EXPECT_EQ(100u, SamplesPerChannel(mono));
     65  EXPECT_TRUE(IsMono(mono));
     66  EXPECT_TRUE(IsMono(const_mono));
     67 }
     68 
     69 TEST(AudioViewTest, InterleavedView) {
     70  const size_t kArraySize = 100u;
     71  int16_t arr[kArraySize];
     72  FillBuffer(ArrayView<int16_t>(arr));
     73 
     74  InterleavedView<int16_t> interleaved(arr, kArraySize, 1);
     75  EXPECT_EQ(NumChannels(interleaved), 1u);
     76  EXPECT_TRUE(IsMono(interleaved));
     77  EXPECT_EQ(SamplesPerChannel(interleaved), kArraySize);
     78  EXPECT_EQ(interleaved.AsMono().size(), kArraySize);
     79  EXPECT_EQ(&interleaved.AsMono()[0], &arr[0]);
     80  EXPECT_EQ(interleaved.AsMono(), interleaved.data());
     81 
     82  // Basic iterator test.
     83  int i = 0;
     84  for (auto s : interleaved) {
     85    EXPECT_EQ(s, arr[i++]);
     86  }
     87 
     88  interleaved = InterleavedView<int16_t>(arr, kArraySize / 2, 2);
     89  InterleavedView<const int16_t> const_interleaved(arr, 50, 2);
     90  EXPECT_EQ(NumChannels(interleaved), 2u);
     91  EXPECT_EQ(NumChannels(const_interleaved), 2u);
     92  EXPECT_EQ(&const_interleaved[0], &interleaved[0]);
     93  EXPECT_TRUE(!IsMono(interleaved));
     94  EXPECT_TRUE(!IsMono(const_interleaved));
     95  EXPECT_EQ(SamplesPerChannel(interleaved), 50u);
     96  EXPECT_EQ(SamplesPerChannel(const_interleaved), 50u);
     97 
     98  interleaved = InterleavedView<int16_t>(arr, 4);
     99  EXPECT_EQ(NumChannels(interleaved), 4u);
    100  InterleavedView<const int16_t> const_interleaved2(interleaved);
    101  EXPECT_EQ(NumChannels(const_interleaved2), 4u);
    102  EXPECT_EQ(SamplesPerChannel(interleaved), 25u);
    103 
    104  const_interleaved2 = interleaved;
    105  EXPECT_EQ(NumChannels(const_interleaved2), 4u);
    106  EXPECT_EQ(&const_interleaved2[0], &interleaved[0]);
    107 }
    108 
    109 TEST(AudioViewTest, DeinterleavedView) {
    110  const size_t kArraySize = 100u;
    111  int16_t arr[kArraySize] = {};
    112  DeinterleavedView<int16_t> di(arr, 10, 10);
    113  DeinterleavedView<const int16_t> const_di(arr, 10, 10);
    114  EXPECT_EQ(NumChannels(di), 10u);
    115  EXPECT_EQ(SamplesPerChannel(di), 10u);
    116  EXPECT_TRUE(!IsMono(di));
    117  EXPECT_EQ(const_di[5][1], di[5][1]);  // Spot check.
    118  // For deinterleaved views, although they may hold multiple channels,
    119  // the AsMono() method is still available and returns the first channel
    120  // in the view.
    121  auto mono_ch = di.AsMono();
    122  EXPECT_EQ(NumChannels(mono_ch), 1u);
    123  EXPECT_EQ(SamplesPerChannel(mono_ch), 10u);
    124  EXPECT_EQ(di[0], mono_ch);  // first channel should be same as mono.
    125 
    126  di = DeinterleavedView<int16_t>(arr, 50, 2);
    127  // Test assignment.
    128  const_di = di;
    129  EXPECT_EQ(&di.AsMono()[0], &const_di.AsMono()[0]);
    130 
    131  // Access the second channel in the deinterleaved view.
    132  // The start of the second channel should be directly after the first channel.
    133  // The memory width of each channel is held by the `stride()` member which
    134  // by default is the same value as samples per channel.
    135  mono_ch = di[1];
    136  EXPECT_EQ(SamplesPerChannel(mono_ch), 50u);
    137  EXPECT_EQ(&mono_ch[0], &arr[di.samples_per_channel()]);
    138 }
    139 
    140 TEST(AudioViewTest, CopySamples) {
    141  const size_t kArraySize = 100u;
    142  int16_t source_arr[kArraySize] = {};
    143  int16_t dest_arr[kArraySize] = {};
    144  FillBuffer(ArrayView<int16_t>(source_arr));
    145 
    146  InterleavedView<const int16_t> source(source_arr, 2);
    147  InterleavedView<int16_t> destination(dest_arr, 2);
    148 
    149  static_assert(IsInterleavedView(source) == IsInterleavedView(destination),
    150                "");
    151 
    152  // Values in `dest_arr` should all be 0, none of the values in `source_arr`
    153  // should be 0.
    154  for (size_t i = 0; i < kArraySize; ++i) {
    155    ASSERT_EQ(dest_arr[i], 0);
    156    ASSERT_NE(source_arr[i], 0);
    157  }
    158 
    159  CopySamples(destination, source);
    160  for (size_t i = 0; i < kArraySize; ++i) {
    161    ASSERT_EQ(dest_arr[i], source_arr[i]) << "i == " << i;
    162  }
    163 }
    164 
    165 TEST(AudioViewTest, ClearSamples) {
    166  std::array<int16_t, 100u> samples = {};
    167  FillBuffer(ArrayView<int16_t>(samples));
    168  ASSERT_NE(samples[0], 0);
    169  ClearSamples(samples);
    170  for (const auto s : samples) {
    171    ASSERT_EQ(s, 0);
    172  }
    173 
    174  std::array<float, 100u> samples_f = {};
    175  FillBuffer(ArrayView<float>(samples_f));
    176  ASSERT_NE(samples_f[0], 0.0);
    177  ClearSamples(samples_f);
    178  for (const auto s : samples_f) {
    179    ASSERT_EQ(s, 0.0);
    180  }
    181 
    182  // Clear only half of the buffer
    183  FillBuffer(ArrayView<int16_t>(samples));
    184  const auto half_way = samples.size() / 2;
    185  ClearSamples(samples, half_way);
    186  for (size_t i = 0u; i < samples.size(); ++i) {
    187    if (i < half_way) {
    188      ASSERT_EQ(samples[i], 0);
    189    } else {
    190      ASSERT_NE(samples[i], 0);
    191    }
    192  }
    193 }
    194 
    195 TEST(AudioViewTest, DeinterleavedViewPointerArray) {
    196  // Create vectors of varying sizes to guarantee that they don't end up
    197  // aligned in memory.
    198  std::vector<float> v1(100), v2(200), v3(300), v4(400);
    199  std::vector<float*> channels = {&v1[0], &v2[0], &v3[0], &v4[0]};
    200 
    201  DeinterleavedView<float> di(channels, v1.size());
    202  EXPECT_EQ(NumChannels(di), channels.size());
    203  EXPECT_EQ(SamplesPerChannel(di), v1.size());
    204  EXPECT_EQ(di[0].data(), v1.data());
    205  EXPECT_EQ(di[1].data(), v2.data());
    206  EXPECT_EQ(di[2].data(), v3.data());
    207  EXPECT_EQ(di[3].data(), v4.data());
    208 
    209  // Test that the same thing works with T* const *.
    210  float* channel_array[] = {&v1[0], &v2[0], &v3[0], &v4[0]};
    211  di = DeinterleavedView<float>(channel_array, v1.size(),
    212                                std::size(channel_array));
    213  EXPECT_EQ(NumChannels(di), channels.size());
    214  EXPECT_EQ(SamplesPerChannel(di), v1.size());
    215  EXPECT_EQ(di[0].data(), v1.data());
    216  EXPECT_EQ(di[1].data(), v2.data());
    217  EXPECT_EQ(di[2].data(), v3.data());
    218  EXPECT_EQ(di[3].data(), v4.data());
    219 }
    220 
    221 }  // namespace webrtc