Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/AudioConfig.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
#if !defined(AudioLayout_h)
7
#define AudioLayout_h
8
9
#include <cstdint>
10
#include <initializer_list>
11
#include "mozilla/MathAlgorithms.h"
12
#include "nsTArray.h"
13
14
namespace mozilla {
15
16
class AudioConfig
17
{
18
public:
19
  // Channel definition is conveniently defined to be in the same order as
20
  // WAVEFORMAT && SMPTE, even though this is unused for now.
21
  enum Channel
22
  {
23
    CHANNEL_INVALID = -1,
24
    CHANNEL_FRONT_LEFT = 0,
25
    CHANNEL_FRONT_RIGHT,
26
    CHANNEL_FRONT_CENTER,
27
    CHANNEL_LFE,
28
    CHANNEL_BACK_LEFT,
29
    CHANNEL_BACK_RIGHT,
30
    CHANNEL_FRONT_LEFT_OF_CENTER,
31
    CHANNEL_FRONT_RIGHT_OF_CENTER,
32
    CHANNEL_BACK_CENTER,
33
    CHANNEL_SIDE_LEFT,
34
    CHANNEL_SIDE_RIGHT,
35
    // From WAVEFORMAT definition.
36
    CHANNEL_TOP_CENTER,
37
    CHANNEL_TOP_FRONT_LEFT,
38
    CHANNEL_TOP_FRONT_CENTER,
39
    CHANNEL_TOP_FRONT_RIGHT,
40
    CHANNEL_TOP_BACK_LEFT,
41
    CHANNEL_TOP_BACK_CENTER,
42
    CHANNEL_TOP_BACK_RIGHT
43
  };
44
45
  class ChannelLayout
46
  {
47
  public:
48
    // The maximum number of channels a channel map can represent.
49
    static constexpr uint32_t MAX_CHANNELS = 32;
50
51
    typedef uint32_t ChannelMap;
52
53
0
    ChannelLayout() : mChannelMap(UNKNOWN_MAP), mValid(false) { }
54
    explicit ChannelLayout(uint32_t aChannels)
55
      : ChannelLayout(aChannels, DefaultLayoutForChannels(aChannels))
56
0
    {
57
0
    }
58
    ChannelLayout(uint32_t aChannels, const Channel* aConfig)
59
      : ChannelLayout()
60
0
    {
61
0
      if (aChannels == 0 || !aConfig) {
62
0
        return;
63
0
      }
64
0
      mChannels.AppendElements(aConfig, aChannels);
65
0
      UpdateChannelMap();
66
0
    }
67
    explicit ChannelLayout(std::initializer_list<Channel> aChannelList)
68
      : ChannelLayout(aChannelList.size(), aChannelList.begin())
69
0
    {
70
0
    }
71
    bool operator==(const ChannelLayout& aOther) const
72
0
    {
73
0
      return mChannels == aOther.mChannels;
74
0
    }
75
    bool operator!=(const ChannelLayout& aOther) const
76
0
    {
77
0
      return mChannels != aOther.mChannels;
78
0
    }
79
    const Channel& operator[](uint32_t aIndex) const
80
0
    {
81
0
      MOZ_ASSERT(mChannels.Length() > aIndex);
82
0
      return mChannels[aIndex];
83
0
    }
84
    uint32_t Count() const
85
0
    {
86
0
      return mChannels.Length();
87
0
    }
88
    ChannelMap Map() const;
89
90
    // Calculate the mapping table from the current layout to aOther such that
91
    // one can easily go from one layout to the other by doing:
92
    // out[channel] = in[map[channel]].
93
    // Returns true if the reordering is possible or false otherwise.
94
    // If true, then aMap, if set, will be updated to contain the mapping table
95
    // allowing conversion from the current layout to aOther.
96
    // If aMap is empty, then MappingTable can be used to simply determine if
97
    // the current layout can be easily reordered to aOther.
98
    bool MappingTable(const ChannelLayout& aOther, nsTArray<uint8_t>* aMap = nullptr) const;
99
0
    bool IsValid() const { return mValid; }
100
    bool HasChannel(Channel aChannel) const
101
    {
102
      return mChannelMap & (1 << aChannel);
103
    }
104
    // Return the number of channels found in this ChannelMap.
105
    static uint32_t Channels(ChannelMap aMap)
106
    {
107
      static_assert(sizeof(ChannelMap) == sizeof(uint32_t),
108
                    "Must adjust ChannelMap type");
109
      return CountPopulation32(aMap);
110
    }
111
112
    static ChannelLayout SMPTEDefault(
113
      const ChannelLayout& aChannelLayout);
114
    static ChannelLayout SMPTEDefault(ChannelMap aMap);
115
116
    static constexpr ChannelMap UNKNOWN_MAP = 0;
117
118
    // Common channel layout definitions.
119
    static constexpr ChannelMap LMONO_MAP = 1 << CHANNEL_FRONT_CENTER;
120
    static constexpr ChannelMap LMONO_LFE_MAP =
121
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
122
    static constexpr ChannelMap LSTEREO_MAP =
123
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT;
124
    static constexpr ChannelMap LSTEREO_LFE_MAP =
125
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE;
126
    static constexpr ChannelMap L3F_MAP = 1 << CHANNEL_FRONT_LEFT |
127
                                        1 << CHANNEL_FRONT_RIGHT |
128
                                        1 << CHANNEL_FRONT_CENTER;
129
    static constexpr ChannelMap L3F_LFE_MAP =
130
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
131
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
132
    static constexpr ChannelMap L2F1_MAP = 1 << CHANNEL_FRONT_LEFT |
133
                                         1 << CHANNEL_FRONT_RIGHT |
134
                                         1 << CHANNEL_BACK_CENTER;
135
    static constexpr ChannelMap L2F1_LFE_MAP =
136
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
137
      1 << CHANNEL_BACK_CENTER;
138
    static constexpr ChannelMap L3F1_MAP =
139
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
140
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_BACK_CENTER;
141
    static constexpr ChannelMap LSURROUND_MAP = L3F1_MAP;
142
    static constexpr ChannelMap L3F1_LFE_MAP =
143
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
144
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER;
145
    static constexpr ChannelMap L2F2_MAP =
146
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
147
      1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
148
    static constexpr ChannelMap L2F2_LFE_MAP =
149
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
150
      1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
151
    static constexpr ChannelMap LQUAD_MAP =
152
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
153
      1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
154
    static constexpr ChannelMap LQUAD_LFE_MAP =
155
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
156
      1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
157
    static constexpr ChannelMap L3F2_MAP =
158
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
159
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_SIDE_LEFT |
160
      1 << CHANNEL_SIDE_RIGHT;
161
    static constexpr ChannelMap L3F2_LFE_MAP =
162
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
163
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_SIDE_LEFT |
164
      1 << CHANNEL_SIDE_RIGHT;
165
    // 3F2_LFE Alias
166
    static constexpr ChannelMap L5POINT1_SURROUND_MAP = L3F2_LFE_MAP;
167
    static constexpr ChannelMap L3F2_BACK_MAP =
168
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
169
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_BACK_LEFT |
170
      1 << CHANNEL_BACK_RIGHT;
171
    static constexpr ChannelMap L3F2_BACK_LFE_MAP =
172
      L3F2_BACK_MAP | 1 << CHANNEL_LFE;
173
    static constexpr ChannelMap L3F3R_LFE_MAP =
174
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
175
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER |
176
      1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
177
    static ChannelLayout L3F4_LFE;
178
    static constexpr ChannelMap L3F4_LFE_MAP =
179
      1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
180
      1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_LEFT |
181
      1 << CHANNEL_BACK_RIGHT | 1 << CHANNEL_SIDE_LEFT |
182
      1 << CHANNEL_SIDE_RIGHT;
183
    // 3F4_LFE Alias
184
    static ChannelLayout L7POINT1_SURROUND;
185
    static constexpr ChannelMap L7POINT1_SURROUND_MAP = L3F4_LFE_MAP;
186
187
  private:
188
    void UpdateChannelMap();
189
    const Channel* DefaultLayoutForChannels(uint32_t aChannels) const;
190
    AutoTArray<Channel, MAX_CHANNELS> mChannels;
191
    ChannelMap mChannelMap;
192
    bool mValid;
193
  };
194
195
  enum SampleFormat
196
  {
197
    FORMAT_NONE = 0,
198
    FORMAT_U8,
199
    FORMAT_S16,
200
    FORMAT_S24LSB,
201
    FORMAT_S24,
202
    FORMAT_S32,
203
    FORMAT_FLT,
204
#if defined(MOZ_SAMPLE_TYPE_FLOAT32)
205
    FORMAT_DEFAULT = FORMAT_FLT
206
#elif defined(MOZ_SAMPLE_TYPE_S16)
207
    FORMAT_DEFAULT = FORMAT_S16
208
#else
209
#error "Not supported audio type"
210
#endif
211
  };
212
213
  AudioConfig(const ChannelLayout& aChannelLayout,
214
              uint32_t aRate,
215
              AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
216
              bool aInterleaved = true);
217
  AudioConfig(const ChannelLayout& aChannelLayout,
218
              uint32_t aChannels,
219
              uint32_t aRate,
220
              AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
221
              bool aInterleaved = true);
222
  // Will create a channel configuration from default SMPTE ordering.
223
  AudioConfig(uint32_t aChannels,
224
              uint32_t aRate,
225
              AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
226
              bool aInterleaved = true);
227
228
0
  const ChannelLayout& Layout() const { return mChannelLayout; }
229
  uint32_t Channels() const
230
0
  {
231
0
    if (!mChannelLayout.IsValid()) {
232
0
      return mChannels;
233
0
    }
234
0
    return mChannelLayout.Count();
235
0
  }
236
0
  uint32_t Rate() const { return mRate; }
237
0
  SampleFormat Format() const { return mFormat; }
238
0
  bool Interleaved() const { return mInterleaved; }
239
  bool operator==(const AudioConfig& aOther) const
240
0
  {
241
0
    return mChannelLayout == aOther.mChannelLayout && mRate == aOther.mRate &&
242
0
           mFormat == aOther.mFormat && mInterleaved == aOther.mInterleaved;
243
0
  }
244
  bool operator!=(const AudioConfig& aOther) const
245
0
  {
246
0
    return !(*this == aOther);
247
0
  }
248
249
  bool IsValid() const
250
  {
251
    return mChannelLayout.IsValid() && Format() != FORMAT_NONE && Rate() > 0;
252
  }
253
254
  static const char* FormatToString(SampleFormat aFormat);
255
  static uint32_t SampleSize(SampleFormat aFormat);
256
  static uint32_t FormatToBits(SampleFormat aFormat);
257
258
private:
259
  // Channels configuration.
260
  ChannelLayout mChannelLayout;
261
262
  // Channel count.
263
  uint32_t mChannels;
264
265
  // Sample rate.
266
  uint32_t mRate;
267
268
  // Sample format.
269
  SampleFormat mFormat;
270
271
  bool mInterleaved;
272
};
273
274
} // namespace mozilla
275
276
#endif // AudioLayout_h