AudioParamTimeline.h (5035B)
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 AudioParamTimeline_h_ 8 #define AudioParamTimeline_h_ 9 10 #include "AudioEventTimeline.h" 11 #include "AudioNodeTrack.h" 12 #include "AudioSegment.h" 13 14 namespace mozilla::dom { 15 16 struct AudioParamEvent final : public AudioTimelineEvent { 17 AudioParamEvent(Type aType, double aTime, float aValue, 18 double aTimeConstant = 0.0) 19 : AudioTimelineEvent(aType, aTime, aValue, aTimeConstant) {} 20 AudioParamEvent(Type aType, const nsTArray<float>& aValues, double aStartTime, 21 double aDuration) 22 : AudioTimelineEvent(aType, aValues, aStartTime, aDuration) {} 23 explicit AudioParamEvent(AudioNodeTrack* aTrack) 24 : AudioTimelineEvent(Track, 0.0, 0.f), mTrack(aTrack) {} 25 26 RefPtr<AudioNodeTrack> mTrack; 27 }; 28 29 // This helper class is used to represent the part of the AudioParam 30 // class that gets sent to AudioNodeEngine instances. In addition to 31 // AudioEventTimeline methods, it holds a pointer to an optional 32 // AudioNodeTrack which represents the AudioNode inputs to the AudioParam. 33 // This AudioNodeTrack is managed by the AudioParam subclass on the main 34 // thread, and can only be obtained from the AudioNodeEngine instances 35 // consuming this class. 36 class AudioParamTimeline : public AudioEventTimeline { 37 typedef AudioEventTimeline BaseClass; 38 39 public: 40 explicit AudioParamTimeline(float aDefaultValue) : BaseClass(aDefaultValue) {} 41 42 AudioNodeTrack* Track() const { return mTrack; } 43 44 bool HasSimpleValue() const { 45 return BaseClass::HasSimpleValue() && 46 (!mTrack || mTrack->LastChunks()[0].IsNull()); 47 } 48 49 template <class TimeType> 50 float GetValueAtTime(TimeType aTime); 51 52 // Prefer this method over GetValueAtTime() only if HasSimpleValue() is 53 // known false. 54 float GetComplexValueAtTime(int64_t aTime); 55 float GetComplexValueAtTime(double aTime) = delete; 56 57 template <typename TimeType> 58 void InsertEvent(const AudioParamEvent& aEvent) { 59 if (aEvent.mType == AudioTimelineEvent::Cancel) { 60 CancelScheduledValues(aEvent.Time<TimeType>()); 61 return; 62 } 63 if (aEvent.mType == AudioTimelineEvent::Track) { 64 mTrack = aEvent.mTrack; 65 return; 66 } 67 AudioEventTimeline::InsertEvent<TimeType>(aEvent); 68 } 69 70 // Get the values of the AudioParam at time aTime + (0 to aSize). 71 // aBuffer must have the correct aSize. 72 // aSize here is an offset to aTime if we try to get the value in ticks, 73 // otherwise it should always be zero. aSize is meant to be used when 74 // getting the value of an a-rate AudioParam for each tick inside an 75 // AudioNodeEngine implementation. 76 void GetValuesAtTime(int64_t aTime, float* aBuffer, const size_t aSize); 77 void GetValuesAtTime(double aTime, float* aBuffer, 78 const size_t aSize) = delete; 79 80 virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { 81 return mTrack ? mTrack->SizeOfIncludingThis(aMallocSizeOf) : 0; 82 } 83 84 virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { 85 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); 86 } 87 88 private: 89 float AudioNodeInputValue(size_t aCounter) const; 90 91 protected: 92 // This is created lazily when needed. 93 RefPtr<AudioNodeTrack> mTrack; 94 }; 95 96 template <> 97 inline float AudioParamTimeline::GetValueAtTime(double aTime) { 98 // Getting an AudioParam value on an AudioNode does not consider input from 99 // other AudioNodes, which is managed only on the graph thread. 100 return BaseClass::GetValueAtTime(aTime); 101 } 102 103 template <> 104 inline float AudioParamTimeline::GetValueAtTime(int64_t aTime) { 105 // Use GetValuesAtTime() for a-rate parameters. 106 MOZ_ASSERT(aTime % WEBAUDIO_BLOCK_SIZE == 0); 107 if (HasSimpleValue()) { 108 return GetValue(); 109 } 110 return GetComplexValueAtTime(aTime); 111 } 112 113 inline float AudioParamTimeline::GetComplexValueAtTime(int64_t aTime) { 114 MOZ_ASSERT(aTime % WEBAUDIO_BLOCK_SIZE == 0); 115 116 // Mix the value of the AudioParam itself with that of the AudioNode inputs. 117 return BaseClass::GetValueAtTime(aTime) + 118 (mTrack ? AudioNodeInputValue(0) : 0.0f); 119 } 120 121 inline void AudioParamTimeline::GetValuesAtTime(int64_t aTime, float* aBuffer, 122 const size_t aSize) { 123 MOZ_ASSERT(aBuffer); 124 MOZ_ASSERT(aSize <= WEBAUDIO_BLOCK_SIZE); 125 MOZ_ASSERT(aSize == 1 || !HasSimpleValue()); 126 127 // Mix the value of the AudioParam itself with that of the AudioNode inputs. 128 BaseClass::GetValuesAtTime(aTime, aBuffer, aSize); 129 if (mTrack) { 130 uint32_t blockOffset = aTime % WEBAUDIO_BLOCK_SIZE; 131 MOZ_ASSERT(blockOffset + aSize <= WEBAUDIO_BLOCK_SIZE); 132 for (size_t i = 0; i < aSize; ++i) { 133 aBuffer[i] += AudioNodeInputValue(blockOffset + i); 134 } 135 } 136 } 137 138 } // namespace mozilla::dom 139 140 #endif