Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/webaudio/PeriodicWave.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:set ts=2 sw=2 sts=2 et cindent: */
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
7
#include "PeriodicWave.h"
8
#include "AudioContext.h"
9
#include "mozilla/dom/PeriodicWaveBinding.h"
10
11
namespace mozilla {
12
namespace dom {
13
14
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PeriodicWave, mContext)
15
16
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PeriodicWave, AddRef)
17
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PeriodicWave, Release)
18
19
PeriodicWave::PeriodicWave(AudioContext* aContext,
20
                           const float* aRealData,
21
                           const float* aImagData,
22
                           const uint32_t aLength,
23
                           const bool aDisableNormalization,
24
                           ErrorResult& aRv)
25
  : mContext(aContext)
26
  , mDisableNormalization(aDisableNormalization)
27
0
{
28
0
  MOZ_ASSERT(aContext);
29
0
  MOZ_ASSERT((aRealData || aImagData) || aLength == 2);
30
0
31
0
  // Caller should have checked this and thrown.
32
0
  MOZ_ASSERT(aLength > 0);
33
0
  mCoefficients.mDuration = aLength;
34
0
35
0
  // Copy coefficient data.
36
0
  // The SharedBuffer and two arrays share a single allocation.
37
0
  RefPtr<SharedBuffer> buffer =
38
0
    SharedBuffer::Create(sizeof(float) * aLength * 2, fallible);
39
0
  if (!buffer) {
40
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
41
0
    return;
42
0
  }
43
0
44
0
  auto data = static_cast<float*>(buffer->Data());
45
0
  mCoefficients.mBuffer = std::move(buffer);
46
0
47
0
  if (!aRealData && !aImagData) {
48
0
    PodZero(data, aLength);
49
0
    mCoefficients.mChannelData.AppendElement(data);
50
0
    data += aLength;
51
0
    data[0] = 0.0f;
52
0
    data[1] = 1.0f;
53
0
    mCoefficients.mChannelData.AppendElement(data);
54
0
  } else {
55
0
    if (aRealData) {
56
0
      PodCopy(data, aRealData, aLength);
57
0
    } else {
58
0
      PodZero(data, aLength);
59
0
    }
60
0
    mCoefficients.mChannelData.AppendElement(data);
61
0
62
0
    data += aLength;
63
0
    if (aImagData) {
64
0
      PodCopy(data, aImagData, aLength);
65
0
    } else {
66
0
      PodZero(data, aLength);
67
0
    }
68
0
    mCoefficients.mChannelData.AppendElement(data);
69
0
  }
70
0
  mCoefficients.mVolume = 1.0f;
71
0
  mCoefficients.mBufferFormat = AUDIO_FORMAT_FLOAT32;
72
0
}
73
74
/* static */ already_AddRefed<PeriodicWave>
75
PeriodicWave::Constructor(const GlobalObject& aGlobal,
76
                          AudioContext& aAudioContext,
77
                          const PeriodicWaveOptions& aOptions,
78
                          ErrorResult& aRv)
79
0
{
80
0
81
0
  if (aOptions.mReal.WasPassed() && aOptions.mImag.WasPassed() &&
82
0
      aOptions.mReal.Value().Length() != aOptions.mImag.Value().Length()) {
83
0
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
84
0
    return nullptr;
85
0
  }
86
0
87
0
  uint32_t length = 0;
88
0
  if (aOptions.mReal.WasPassed()) {
89
0
    length = aOptions.mReal.Value().Length();
90
0
  } else if (aOptions.mImag.WasPassed()) {
91
0
    length = aOptions.mImag.Value().Length();
92
0
  } else {
93
0
    // If nothing has been passed, this PeriodicWave will be a sine wave: 2
94
0
    // elements for each array, the second imaginary component set to 1.0.
95
0
    length = 2;
96
0
  }
97
0
98
0
  if (length == 0) {
99
0
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
100
0
    return nullptr;
101
0
  }
102
0
103
0
  const float* realData =
104
0
    aOptions.mReal.WasPassed() ? aOptions.mReal.Value().Elements() : nullptr;
105
0
  const float* imagData =
106
0
    aOptions.mImag.WasPassed() ? aOptions.mImag.Value().Elements() : nullptr;
107
0
108
0
  RefPtr<PeriodicWave> wave =
109
0
    new PeriodicWave(&aAudioContext, realData, imagData, length,
110
0
                     aOptions.mDisableNormalization, aRv);
111
0
  if (aRv.Failed()) {
112
0
    return nullptr;
113
0
  }
114
0
115
0
  return wave.forget();
116
0
}
117
118
size_t
119
PeriodicWave::SizeOfExcludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
120
0
{
121
0
  // Not owned:
122
0
  // - mContext
123
0
  size_t amount = 0;
124
0
  amount += mCoefficients.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
125
0
126
0
  return amount;
127
0
}
128
129
size_t
130
PeriodicWave::SizeOfIncludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
131
0
{
132
0
  return aMallocSizeOf(this) + SizeOfExcludingThisIfNotShared(aMallocSizeOf);
133
0
}
134
135
JSObject*
136
PeriodicWave::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
137
0
{
138
0
  return PeriodicWave_Binding::Wrap(aCx, this, aGivenProto);
139
0
}
140
141
} // namespace dom
142
} // namespace mozilla