Line data Source code
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 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PeriodicWave, mContext)
15 :
16 0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PeriodicWave, AddRef)
17 0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PeriodicWave, Release)
18 :
19 0 : PeriodicWave::PeriodicWave(AudioContext* aContext,
20 : const float* aRealData,
21 : const float* aImagData,
22 : const uint32_t aLength,
23 : const bool aDisableNormalization,
24 0 : ErrorResult& aRv)
25 : : mContext(aContext)
26 0 : , mDisableNormalization(aDisableNormalization)
27 : {
28 0 : MOZ_ASSERT(aContext);
29 0 : MOZ_ASSERT(aRealData || aImagData);
30 :
31 : // Caller should have checked this and thrown.
32 0 : MOZ_ASSERT(aLength > 0);
33 0 : mLength = aLength;
34 :
35 : // Copy coefficient data. The two arrays share an allocation.
36 0 : mCoefficients = new ThreadSharedFloatArrayBufferList(2);
37 0 : float* buffer = static_cast<float*>(malloc(aLength*sizeof(float)*2));
38 0 : if (buffer == nullptr) {
39 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
40 0 : return;
41 : }
42 :
43 0 : if (aRealData) {
44 0 : PodCopy(buffer, aRealData, aLength);
45 : } else {
46 0 : PodZero(buffer, aLength);
47 : }
48 :
49 0 : mCoefficients->SetData(0, buffer, free, buffer);
50 :
51 0 : if (aImagData) {
52 0 : PodCopy(buffer+aLength, aImagData, aLength);
53 : } else {
54 0 : PodZero(buffer+aLength, aLength);
55 : }
56 :
57 0 : mCoefficients->SetData(1, nullptr, free, buffer+aLength);
58 : }
59 :
60 : /* static */ already_AddRefed<PeriodicWave>
61 0 : PeriodicWave::Constructor(const GlobalObject& aGlobal,
62 : AudioContext& aAudioContext,
63 : const PeriodicWaveOptions& aOptions,
64 : ErrorResult& aRv)
65 : {
66 0 : if (!aOptions.mReal.WasPassed() && !aOptions.mImag.WasPassed()) {
67 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
68 0 : return nullptr;
69 : }
70 :
71 0 : if (aOptions.mReal.WasPassed() && aOptions.mImag.WasPassed() &&
72 0 : aOptions.mReal.Value().Length() != aOptions.mImag.Value().Length()) {
73 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
74 0 : return nullptr;
75 : }
76 :
77 : uint32_t length =
78 0 : aOptions.mReal.WasPassed() ? aOptions.mReal.Value().Length() : aOptions.mImag.Value().Length();
79 0 : if (length == 0) {
80 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
81 0 : return nullptr;
82 : }
83 :
84 : const float* realData =
85 0 : aOptions.mReal.WasPassed() ? aOptions.mReal.Value().Elements() : nullptr;
86 : const float* imagData =
87 0 : aOptions.mImag.WasPassed() ? aOptions.mImag.Value().Elements() : nullptr;
88 :
89 : RefPtr<PeriodicWave> wave =
90 : new PeriodicWave(&aAudioContext, realData, imagData, length,
91 0 : aOptions.mDisableNormalization, aRv);
92 0 : if (aRv.Failed()) {
93 0 : return nullptr;
94 : }
95 :
96 0 : return wave.forget();
97 : }
98 :
99 : size_t
100 0 : PeriodicWave::SizeOfExcludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
101 : {
102 : // Not owned:
103 : // - mContext
104 0 : size_t amount = 0;
105 0 : if (!mCoefficients->IsShared()) {
106 0 : amount += mCoefficients->SizeOfIncludingThis(aMallocSizeOf);
107 : }
108 :
109 0 : return amount;
110 : }
111 :
112 : size_t
113 0 : PeriodicWave::SizeOfIncludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
114 : {
115 0 : return aMallocSizeOf(this) + SizeOfExcludingThisIfNotShared(aMallocSizeOf);
116 : }
117 :
118 : JSObject*
119 0 : PeriodicWave::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
120 : {
121 0 : return PeriodicWaveBinding::Wrap(aCx, this, aGivenProto);
122 : }
123 :
124 : } // namespace dom
125 : } // namespace mozilla
|