AudioBuffer.h (4888B)
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 #ifndef AudioBuffer_h_ 8 #define AudioBuffer_h_ 9 10 #include "AudioSegment.h" 11 #include "js/TypeDecls.h" 12 #include "mozilla/MemoryReporting.h" 13 #include "mozilla/StaticMutex.h" 14 #include "mozilla/StaticPtr.h" 15 #include "mozilla/dom/TypedArray.h" 16 #include "nsCycleCollectionParticipant.h" 17 #include "nsIWeakReferenceUtils.h" 18 #include "nsPIDOMWindow.h" 19 #include "nsTArray.h" 20 #include "nsWrapperCache.h" 21 22 namespace mozilla { 23 24 class ErrorResult; 25 class ThreadSharedFloatArrayBufferList; 26 27 namespace dom { 28 29 struct AudioBufferOptions; 30 31 /** 32 * An AudioBuffer keeps its data either in the mJSChannels objects, which 33 * are Float32Arrays, or in mSharedChannels if the mJSChannels objects' buffers 34 * are detached. 35 */ 36 class AudioBuffer final : public nsWrapperCache { 37 public: 38 // If non-null, aInitialContents must have number of channels equal to 39 // aNumberOfChannels and their lengths must be at least aLength. 40 static already_AddRefed<AudioBuffer> Create( 41 nsPIDOMWindowInner* aWindow, uint32_t aNumberOfChannels, uint32_t aLength, 42 float aSampleRate, 43 already_AddRefed<ThreadSharedFloatArrayBufferList> aInitialContents, 44 ErrorResult& aRv); 45 46 static already_AddRefed<AudioBuffer> Create(nsPIDOMWindowInner* aWindow, 47 uint32_t aNumberOfChannels, 48 uint32_t aLength, 49 float aSampleRate, 50 ErrorResult& aRv) { 51 return Create(aWindow, aNumberOfChannels, aLength, aSampleRate, nullptr, 52 aRv); 53 } 54 55 // Non-unit AudioChunk::mVolume is not supported 56 static already_AddRefed<AudioBuffer> Create(nsPIDOMWindowInner* aWindow, 57 float aSampleRate, 58 AudioChunk&& aInitialContents); 59 60 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 61 62 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioBuffer) 63 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioBuffer) 64 65 static already_AddRefed<AudioBuffer> Constructor( 66 const GlobalObject& aGlobal, const AudioBufferOptions& aOptions, 67 ErrorResult& aRv); 68 69 nsPIDOMWindowInner* GetParentObject() const { 70 nsCOMPtr<nsPIDOMWindowInner> parentObject = do_QueryReferent(mOwnerWindow); 71 return parentObject; 72 } 73 74 JSObject* WrapObject(JSContext* aCx, 75 JS::Handle<JSObject*> aGivenProto) override; 76 77 float SampleRate() const { return mSampleRate; } 78 79 uint32_t Length() const { return mSharedChannels.mDuration; } 80 81 double Duration() const { 82 return Length() / static_cast<double>(mSampleRate); 83 } 84 85 uint32_t NumberOfChannels() const { return mJSChannels.Length(); } 86 87 /** 88 * If mSharedChannels is non-null, copies its contents to 89 * new Float32Arrays in mJSChannels. Returns a Float32Array. 90 */ 91 void GetChannelData(JSContext* aJSContext, uint32_t aChannel, 92 JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv); 93 94 void CopyFromChannel(const Float32Array& aDestination, 95 uint32_t aChannelNumber, uint32_t aBufferOffset, 96 ErrorResult& aRv); 97 void CopyToChannel(JSContext* aJSContext, const Float32Array& aSource, 98 uint32_t aChannelNumber, uint32_t aBufferOffset, 99 ErrorResult& aRv); 100 101 /** 102 * Returns a reference to an AudioChunk containing the sample data. 103 * The AudioChunk can have a null buffer if there is no data. 104 */ 105 const AudioChunk& GetThreadSharedChannelsForRate(JSContext* aContext); 106 107 protected: 108 AudioBuffer(nsPIDOMWindowInner* aWindow, uint32_t aNumberOfChannels, 109 uint32_t aLength, float aSampleRate, ErrorResult& aRv); 110 ~AudioBuffer(); 111 112 void SetSharedChannels( 113 already_AddRefed<ThreadSharedFloatArrayBufferList> aBuffer); 114 115 bool RestoreJSChannelData(JSContext* aJSContext); 116 117 already_AddRefed<ThreadSharedFloatArrayBufferList> 118 StealJSArrayDataIntoSharedChannels(JSContext* aJSContext); 119 120 void ClearJSChannels(); 121 122 // Float32Arrays 123 AutoTArray<JS::Heap<JSObject*>, 2> mJSChannels; 124 // mSharedChannels aggregates the data from mJSChannels. This is non-null 125 // if and only if the mJSChannels' buffers are detached, but its mDuration 126 // member keeps the buffer length regardless of whether the buffer is 127 // provided by mJSChannels or mSharedChannels. 128 AudioChunk mSharedChannels; 129 130 nsWeakPtr mOwnerWindow; 131 float mSampleRate; 132 }; 133 134 } // namespace dom 135 } // namespace mozilla 136 137 #endif