• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 3-Clause Clear License
5  * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6  * License was not distributed with this source code in the LICENSE file, you
7  * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8  * Alliance for Open Media Patent License 1.0 was not distributed with this
9  * source code in the PATENTS file, you can obtain it at
10  * www.aomedia.org/license/patent.
11  */
12 
13 #include <algorithm>
14 #include <cstddef>
15 #include <cstdlib>
16 #include <utility>
17 #include <vector>
18 
19 #include "benchmark/benchmark.h"
20 #include "iamf/cli/ambisonic_encoder/ambisonic_encoder.h"
21 
22 namespace iamf_tools {
23 namespace {
24 
25 // Measure execution time of coefficient calculation using both implemented
26 // methods.
BM_SHCalculation(benchmark::State & state)27 static void BM_SHCalculation(benchmark::State& state) {
28   const size_t buffer_size = 1;
29   const int number_of_input_channels = 512;
30   const int ambisonic_order = 7;
31 
32   // Create an array of azimuth/elevation pairs with random directions.
33   std::vector<std::pair<float, float>> directions;
34   for (int i = 0; i < number_of_input_channels; i++) {
35     float azimuth =
36         static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * 360.0f;
37     float elevation =
38         static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * 180.0f -
39         90.0f;
40     directions.push_back(std::make_pair(azimuth, elevation));
41   }
42 
43   // Create an Ambisonic encoder object.
44   AmbisonicEncoder encoder(buffer_size, number_of_input_channels,
45                            ambisonic_order);
46 
47   for (auto _ : state) {
48     // Assign sources to the encoder at all available input channels.
49     for (int i = 0; i < number_of_input_channels; i++) {
50       encoder.SetSource(i, 1.0f, directions[i].first, directions[i].second,
51                         1.0f);
52     }
53   }
54 }
55 
56 BENCHMARK(BM_SHCalculation)->Args({0})->Args({1});
57 
58 // Measure matrix multiplication time at different numbers of input channels.
59 // Test with matrix data set to zeros and filled with random data.
60 // TODO(b/374695317): Optimise matrix multiplication to avoid multiplication by
61 //                    columns of zeros (inactive inputs).
BM_MatrixMultiplication(benchmark::State & state)62 static void BM_MatrixMultiplication(benchmark::State& state) {
63   const size_t buffer_size = 256;
64   const int number_of_input_channels = state.range(0);
65   const int ambisonic_order = 7;
66   const bool fill_with_random_data = state.range(1) == 1;
67 
68   // Create input buffer
69   std::vector<float> input_buffer(number_of_input_channels * buffer_size, 0.0f);
70   if (fill_with_random_data) {
71     std::generate(input_buffer.begin(), input_buffer.end(), []() {
72       return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
73     });
74   } else {
75     std::fill(input_buffer.begin(), input_buffer.end(), 0.0f);
76   }
77 
78   // Create output buffer.
79   std::vector<float> output_buffer(
80       (ambisonic_order + 1) * (ambisonic_order + 1) * buffer_size, 0.0f);
81 
82   // Create an Ambisonic encoder object.
83   AmbisonicEncoder encoder(buffer_size, number_of_input_channels,
84                            ambisonic_order);
85 
86   // Create an array of azimuth/elevation pairs with random directions.
87   std::vector<std::pair<float, float>> directions;
88   for (int i = 0; i < number_of_input_channels; i++) {
89     float azimuth =
90         static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * 360.0f;
91     float elevation =
92         static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * 180.0f -
93         90.0f;
94     directions.push_back(std::make_pair(azimuth, elevation));
95   }
96 
97   // Assign sources to the encoder at all available input channels.
98   for (int i = 0; i < number_of_input_channels; i++) {
99     encoder.SetSource(i, 1.0f, directions[i].first, directions[i].second, 1.0f);
100   }
101 
102   for (auto _ : state) {
103     // Perform matrix multiplication.
104     encoder.ProcessPlanarAudioData(input_buffer, output_buffer);
105   }
106 }
107 
108 // Setup benchmark
109 BENCHMARK(BM_MatrixMultiplication)
110     ->Args({16, 0})
111     ->Args({16, 1})
112     ->Args({32, 0})
113     ->Args({32, 1})
114     ->Args({64, 0})
115     ->Args({64, 1})
116     ->Args({128, 0})
117     ->Args({128, 1});
118 
119 }  // namespace
120 }  // namespace iamf_tools
121