Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/gtest/TestAudioPacketizer.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 <stdint.h>
7
#include <math.h>
8
#include <memory>
9
#include "../AudioPacketizer.h"
10
#include "gtest/gtest.h"
11
12
using namespace mozilla;
13
14
template<typename T>
15
class AutoBuffer
16
{
17
public:
18
  explicit AutoBuffer(size_t aLength)
19
0
  {
20
0
    mStorage = new T[aLength];
21
0
  }
22
0
  ~AutoBuffer() {
23
0
    delete [] mStorage;
24
0
  }
25
0
  T* Get() {
26
0
    return mStorage;
27
0
  }
28
private:
29
  T* mStorage;
30
};
31
32
int16_t Sequence(int16_t* aBuffer, uint32_t aSize, uint32_t aStart = 0)
33
0
{
34
0
  uint32_t i;
35
0
  for (i = 0; i < aSize; i++) {
36
0
    aBuffer[i] = aStart + i;
37
0
  }
38
0
  return aStart + i;
39
0
}
40
41
void IsSequence(std::unique_ptr<int16_t[]> aBuffer, uint32_t aSize, uint32_t aStart = 0)
42
0
{
43
0
  for (uint32_t i = 0; i < aSize; i++) {
44
0
    ASSERT_TRUE(aBuffer[i] == static_cast<int64_t>(aStart + i)) <<
45
0
      "Buffer is not a sequence at offset " << i << std::endl;
46
0
  }
47
0
  // Buffer is a sequence.
48
0
}
49
50
void Zero(std::unique_ptr<int16_t[]> aBuffer, uint32_t aSize)
51
0
{
52
0
  for (uint32_t i = 0; i < aSize; i++) {
53
0
    ASSERT_TRUE(aBuffer[i] == 0) <<
54
0
      "Buffer is not null at offset " << i << std::endl;
55
0
  }
56
0
}
57
58
0
double sine(uint32_t aPhase) {
59
0
  return sin(aPhase * 2 * M_PI * 440 / 44100);
60
0
}
61
62
TEST(AudioPacketizer, Test)
63
0
{
64
0
  for (int16_t channels = 1; channels < 2; channels++) {
65
0
    // Test that the packetizer returns zero on underrun
66
0
    {
67
0
      AudioPacketizer<int16_t, int16_t> ap(441, channels);
68
0
      for (int16_t i = 0; i < 10; i++) {
69
0
        std::unique_ptr<int16_t[]> out(ap.Output());
70
0
        Zero(std::move(out), 441);
71
0
      }
72
0
    }
73
0
    // Simple test, with input/output buffer size aligned on the packet size,
74
0
    // alternating Input and Output calls.
75
0
    {
76
0
      AudioPacketizer<int16_t, int16_t> ap(441, channels);
77
0
      int16_t seqEnd = 0;
78
0
      for (int16_t i = 0; i < 10; i++) {
79
0
        AutoBuffer<int16_t> b(441 * channels);
80
0
        int16_t prevEnd = seqEnd;
81
0
        seqEnd = Sequence(b.Get(), channels * 441, prevEnd);
82
0
        ap.Input(b.Get(), 441);
83
0
        std::unique_ptr<int16_t[]> out(ap.Output());
84
0
        IsSequence(std::move(out), 441 * channels, prevEnd);
85
0
      }
86
0
    }
87
0
    // Simple test, with input/output buffer size aligned on the packet size,
88
0
    // alternating two Input and Output calls.
89
0
    {
90
0
      AudioPacketizer<int16_t, int16_t> ap(441, channels);
91
0
      int16_t seqEnd = 0;
92
0
      for (int16_t i = 0; i < 10; i++) {
93
0
        AutoBuffer<int16_t> b(441 * channels);
94
0
        AutoBuffer<int16_t> b1(441 * channels);
95
0
        int16_t prevEnd0 = seqEnd;
96
0
        seqEnd = Sequence(b.Get(), 441 * channels, prevEnd0);
97
0
        int16_t prevEnd1 = seqEnd;
98
0
        seqEnd = Sequence(b1.Get(), 441 * channels, seqEnd);
99
0
        ap.Input(b.Get(), 441);
100
0
        ap.Input(b1.Get(), 441);
101
0
        std::unique_ptr<int16_t[]> out(ap.Output());
102
0
        std::unique_ptr<int16_t[]> out2(ap.Output());
103
0
        IsSequence(std::move(out), 441 * channels, prevEnd0);
104
0
        IsSequence(std::move(out2), 441 * channels, prevEnd1);
105
0
      }
106
0
    }
107
0
    // Input/output buffer size not aligned on the packet size,
108
0
    // alternating two Input and Output calls.
109
0
    {
110
0
      AudioPacketizer<int16_t, int16_t> ap(441, channels);
111
0
      int16_t prevEnd = 0;
112
0
      int16_t prevSeq = 0;
113
0
      for (int16_t i = 0; i < 10; i++) {
114
0
        AutoBuffer<int16_t> b(480 * channels);
115
0
        AutoBuffer<int16_t> b1(480 * channels);
116
0
        prevSeq = Sequence(b.Get(), 480 * channels, prevSeq);
117
0
        prevSeq = Sequence(b1.Get(), 480 * channels, prevSeq);
118
0
        ap.Input(b.Get(), 480);
119
0
        ap.Input(b1.Get(), 480);
120
0
        std::unique_ptr<int16_t[]> out(ap.Output());
121
0
        std::unique_ptr<int16_t[]> out2(ap.Output());
122
0
        IsSequence(std::move(out), 441 * channels, prevEnd);
123
0
        prevEnd += 441 * channels;
124
0
        IsSequence(std::move(out2), 441 * channels, prevEnd);
125
0
        prevEnd += 441 * channels;
126
0
      }
127
0
      printf("Available: %d\n", ap.PacketsAvailable());
128
0
    }
129
0
130
0
    // "Real-life" test case: streaming a sine wave through a packetizer, and
131
0
    // checking that we have the right output.
132
0
    // 128 is, for example, the size of a Web Audio API block, and 441 is the
133
0
    // size of a webrtc.org packet when the sample rate is 44100 (10ms)
134
0
    {
135
0
      AudioPacketizer<int16_t, int16_t> ap(441, channels);
136
0
      AutoBuffer<int16_t> b(128 * channels);
137
0
      uint32_t phase = 0;
138
0
      uint32_t outPhase = 0;
139
0
      for (int16_t i = 0; i < 1000; i++) {
140
0
        for (int32_t j = 0; j < 128; j++) {
141
0
          for (int32_t c = 0; c < channels; c++) {
142
0
            // int16_t sinewave at 440Hz/44100Hz sample rate
143
0
            b.Get()[j * channels + c] = (2 << 14) * sine(phase);
144
0
          }
145
0
          phase++;
146
0
        }
147
0
        ap.Input(b.Get(), 128);
148
0
        while (ap.PacketsAvailable()) {
149
0
          std::unique_ptr<int16_t[]> packet(ap.Output());
150
0
          for (uint32_t k = 0; k < ap.PacketSize(); k++) {
151
0
            for (int32_t c = 0; c < channels; c++) {
152
0
              ASSERT_TRUE(packet[k * channels + c] ==
153
0
                          static_cast<int16_t>(((2 << 14) * sine(outPhase))));
154
0
            }
155
0
            outPhase++;
156
0
          }
157
0
        }
158
0
      }
159
0
    }
160
0
  }
161
0
}