Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/gtest/TestAudioSegment.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "AudioSegment.h"
7
#include <iostream>
8
#include "gtest/gtest.h"
9
10
using namespace mozilla;
11
12
namespace audio_segment {
13
14
/* Helper function to give us the maximum and minimum value that don't clip,
15
 * for a given sample format (integer or floating-point). */
16
template<typename T>
17
T GetLowValue();
18
19
template<typename T>
20
T GetHighValue();
21
22
template<typename T>
23
T GetSilentValue();
24
25
template<>
26
0
float GetLowValue<float>() {
27
0
  return -1.0;
28
0
}
29
30
template<>
31
0
int16_t GetLowValue<short>() {
32
0
  return -INT16_MAX;
33
0
}
34
35
template<>
36
0
float GetHighValue<float>() {
37
0
  return 1.0;
38
0
}
39
40
template<>
41
0
int16_t GetHighValue<short>() {
42
0
  return INT16_MAX;
43
0
}
44
45
template<>
46
0
float GetSilentValue() {
47
0
  return 0.0;
48
0
}
49
50
template<>
51
0
int16_t GetSilentValue() {
52
0
  return 0;
53
0
}
54
55
56
// Get an array of planar audio buffers that has the inverse of the index of the
57
// channel (1-indexed) as samples.
58
template<typename T>
59
const T* const* GetPlanarChannelArray(size_t aChannels, size_t aSize)
60
0
{
61
0
  T** channels = new T*[aChannels];
62
0
  for (size_t c = 0; c < aChannels; c++) {
63
0
    channels[c] = new T[aSize];
64
0
    for (size_t i = 0; i < aSize; i++) {
65
0
      channels[c][i] = FloatToAudioSample<T>(1. / (c + 1));
66
0
    }
67
0
  }
68
0
  return channels;
69
0
}
Unexecuted instantiation: float const* const* audio_segment::GetPlanarChannelArray<float>(unsigned long, unsigned long)
Unexecuted instantiation: short const* const* audio_segment::GetPlanarChannelArray<short>(unsigned long, unsigned long)
70
71
template<typename T>
72
void DeletePlanarChannelsArray(const T* const* aArrays, size_t aChannels)
73
0
{
74
0
  for (size_t channel = 0; channel < aChannels; channel++) {
75
0
    delete [] aArrays[channel];
76
0
  }
77
0
  delete [] aArrays;
78
0
}
Unexecuted instantiation: void audio_segment::DeletePlanarChannelsArray<float>(float const* const*, unsigned long)
Unexecuted instantiation: void audio_segment::DeletePlanarChannelsArray<short>(short const* const*, unsigned long)
79
80
template<typename T>
81
T** GetPlanarArray(size_t aChannels, size_t aSize)
82
0
{
83
0
  T** channels = new T*[aChannels];
84
0
  for (size_t c = 0; c < aChannels; c++) {
85
0
    channels[c] = new T[aSize];
86
0
    for (size_t i = 0; i < aSize; i++) {
87
0
      channels[c][i] = 0.0f;
88
0
    }
89
0
  }
90
0
  return channels;
91
0
}
Unexecuted instantiation: float** audio_segment::GetPlanarArray<float>(unsigned long, unsigned long)
Unexecuted instantiation: short** audio_segment::GetPlanarArray<short>(unsigned long, unsigned long)
92
93
template<typename T>
94
void DeletePlanarArray(T** aArrays, size_t aChannels)
95
0
{
96
0
  for (size_t channel = 0; channel < aChannels; channel++) {
97
0
    delete [] aArrays[channel];
98
0
  }
99
0
  delete [] aArrays;
100
0
}
Unexecuted instantiation: void audio_segment::DeletePlanarArray<float>(float**, unsigned long)
Unexecuted instantiation: void audio_segment::DeletePlanarArray<short>(short**, unsigned long)
101
102
// Get an array of audio samples that have the inverse of the index of the
103
// channel (1-indexed) as samples.
104
template<typename T>
105
const T* GetInterleavedChannelArray(size_t aChannels, size_t aSize)
106
0
{
107
0
  size_t sampleCount = aChannels * aSize;
108
0
  T* samples = new T[sampleCount];
109
0
  for (size_t i = 0; i < sampleCount; i++) {
110
0
    uint32_t channel = (i % aChannels) + 1;
111
0
    samples[i] = FloatToAudioSample<T>(1. / channel);
112
0
  }
113
0
  return samples;
114
0
}
Unexecuted instantiation: float const* audio_segment::GetInterleavedChannelArray<float>(unsigned long, unsigned long)
Unexecuted instantiation: short const* audio_segment::GetInterleavedChannelArray<short>(unsigned long, unsigned long)
115
116
template<typename T>
117
void DeleteInterleavedChannelArray(const T* aArray)
118
0
{
119
0
  delete [] aArray;
120
0
}
Unexecuted instantiation: void audio_segment::DeleteInterleavedChannelArray<float>(float const*)
Unexecuted instantiation: void audio_segment::DeleteInterleavedChannelArray<short>(short const*)
121
122
0
bool FuzzyEqual(float aLhs, float aRhs) {
123
0
  return std::abs(aLhs - aRhs) < 0.01;
124
0
}
125
126
template<typename SrcT, typename DstT>
127
void TestInterleaveAndConvert()
128
0
{
129
0
  size_t arraySize = 1024;
130
0
  size_t maxChannels = 8; // 7.1
131
0
  for (uint32_t channels = 1; channels < maxChannels; channels++) {
132
0
    const SrcT* const* src = GetPlanarChannelArray<SrcT>(channels, arraySize);
133
0
    DstT* dst = new DstT[channels * arraySize];
134
0
135
0
    InterleaveAndConvertBuffer(src, arraySize, 1.0, channels, dst);
136
0
137
0
    uint32_t channelIndex = 0;
138
0
    for (size_t i = 0; i < arraySize * channels; i++) {
139
0
      ASSERT_TRUE(FuzzyEqual(dst[i],
140
0
                  FloatToAudioSample<DstT>(1. / (channelIndex + 1))));
141
0
      channelIndex++;
142
0
      channelIndex %= channels;
143
0
    }
144
0
145
0
    DeletePlanarChannelsArray(src, channels);
146
0
    delete [] dst;
147
0
  }
148
0
}
Unexecuted instantiation: void audio_segment::TestInterleaveAndConvert<float, float>()
Unexecuted instantiation: void audio_segment::TestInterleaveAndConvert<float, short>()
Unexecuted instantiation: void audio_segment::TestInterleaveAndConvert<short, float>()
Unexecuted instantiation: void audio_segment::TestInterleaveAndConvert<short, short>()
149
150
template<typename SrcT, typename DstT>
151
void TestDeinterleaveAndConvert()
152
0
{
153
0
  size_t arraySize = 1024;
154
0
  size_t maxChannels = 8; // 7.1
155
0
  for (uint32_t channels = 1; channels < maxChannels; channels++) {
156
0
    const SrcT* src = GetInterleavedChannelArray<SrcT>(channels, arraySize);
157
0
    DstT** dst = GetPlanarArray<DstT>(channels, arraySize);
158
0
159
0
    DeinterleaveAndConvertBuffer(src, arraySize, channels, dst);
160
0
161
0
    for (size_t channel = 0; channel < channels; channel++) {
162
0
      for (size_t i = 0; i < arraySize; i++) {
163
0
        ASSERT_TRUE(FuzzyEqual(dst[channel][i],
164
0
                    FloatToAudioSample<DstT>(1. / (channel + 1))));
165
0
      }
166
0
    }
167
0
168
0
    DeleteInterleavedChannelArray(src);
169
0
    DeletePlanarArray(dst, channels);
170
0
  }
171
0
}
Unexecuted instantiation: void audio_segment::TestDeinterleaveAndConvert<float, float>()
Unexecuted instantiation: void audio_segment::TestDeinterleaveAndConvert<float, short>()
Unexecuted instantiation: void audio_segment::TestDeinterleaveAndConvert<short, float>()
Unexecuted instantiation: void audio_segment::TestDeinterleaveAndConvert<short, short>()
172
173
uint8_t gSilence[4096] = {0};
174
175
template<typename T>
176
T* SilentChannel()
177
0
{
178
0
  return reinterpret_cast<T*>(gSilence);
179
0
}
Unexecuted instantiation: float* audio_segment::SilentChannel<float>()
Unexecuted instantiation: short* audio_segment::SilentChannel<short>()
180
181
template<typename T>
182
void TestUpmixStereo()
183
0
{
184
0
  size_t arraySize = 1024;
185
0
  nsTArray<T*> channels;
186
0
  nsTArray<const T*> channelsptr;
187
0
188
0
  channels.SetLength(1);
189
0
  channelsptr.SetLength(1);
190
0
191
0
  channels[0] = new T[arraySize];
192
0
193
0
  for (size_t i = 0; i < arraySize; i++) {
194
0
    channels[0][i] = GetHighValue<T>();
195
0
  }
196
0
  channelsptr[0] = channels[0];
197
0
198
0
  AudioChannelsUpMix(&channelsptr, 2, SilentChannel<T>());
199
0
200
0
  for (size_t channel = 0; channel < 2; channel++) {
201
0
    for (size_t i = 0; i < arraySize; i++) {
202
0
      ASSERT_TRUE(channelsptr[channel][i] == GetHighValue<T>());
203
0
    }
204
0
  }
205
0
  delete [] channels[0];
206
0
}
Unexecuted instantiation: void audio_segment::TestUpmixStereo<float>()
Unexecuted instantiation: void audio_segment::TestUpmixStereo<short>()
207
208
template<typename T>
209
void TestDownmixStereo()
210
0
{
211
0
  const size_t arraySize = 1024;
212
0
  nsTArray<const T*> inputptr;
213
0
  nsTArray<T*> input;
214
0
  T** output;
215
0
216
0
  output = new T*[1];
217
0
  output[0] = new T[arraySize];
218
0
219
0
  input.SetLength(2);
220
0
  inputptr.SetLength(2);
221
0
222
0
  for (size_t channel = 0; channel < input.Length(); channel++) {
223
0
    input[channel] = new T[arraySize];
224
0
    for (size_t i = 0; i < arraySize; i++) {
225
0
      input[channel][i] = channel == 0 ? GetLowValue<T>() : GetHighValue<T>();
226
0
    }
227
0
    inputptr[channel] = input[channel];
228
0
  }
229
0
230
0
  AudioChannelsDownMix(inputptr, output, 1, arraySize);
231
0
232
0
  for (size_t i = 0; i < arraySize; i++) {
233
0
    ASSERT_TRUE(output[0][i] == GetSilentValue<T>());
234
0
    ASSERT_TRUE(output[0][i] == GetSilentValue<T>());
235
0
  }
236
0
237
0
  delete [] output[0];
238
0
  delete [] output;
239
0
}
Unexecuted instantiation: void audio_segment::TestDownmixStereo<float>()
Unexecuted instantiation: void audio_segment::TestDownmixStereo<short>()
240
241
TEST(AudioSegment, Test)
242
0
{
243
0
  TestInterleaveAndConvert<float, float>();
244
0
  TestInterleaveAndConvert<float, int16_t>();
245
0
  TestInterleaveAndConvert<int16_t, float>();
246
0
  TestInterleaveAndConvert<int16_t, int16_t>();
247
0
  TestDeinterleaveAndConvert<float, float>();
248
0
  TestDeinterleaveAndConvert<float, int16_t>();
249
0
  TestDeinterleaveAndConvert<int16_t, float>();
250
0
  TestDeinterleaveAndConvert<int16_t, int16_t>();
251
0
  TestUpmixStereo<float>();
252
0
  TestUpmixStereo<int16_t>();
253
0
  TestDownmixStereo<float>();
254
0
  TestDownmixStereo<int16_t>();
255
0
}
256
257
} // namespace audio_segment