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 AudioDestinationNode_h_ 8 #define AudioDestinationNode_h_ 9 10 #include "AudioChannelService.h" 11 #include "AudioNode.h" 12 #include "AudioChannelAgent.h" 13 #include "mozilla/TimeStamp.h" 14 15 namespace mozilla { 16 namespace dom { 17 18 class AudioContext; 19 class WakeLock; 20 21 class AudioDestinationNode final : public AudioNode, 22 public nsIAudioChannelAgentCallback, 23 public MainThreadMediaTrackListener { 24 public: 25 // This node type knows what MediaTrackGraph to use based on 26 // whether it's in offline mode. 27 AudioDestinationNode(AudioContext* aContext, bool aIsOffline, 28 uint32_t aNumberOfChannels, uint32_t aLength); 29 30 void DestroyMediaTrack() override; 31 32 NS_DECL_ISUPPORTS_INHERITED 33 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioDestinationNode, AudioNode) 34 NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK 35 36 JSObject* WrapObject(JSContext* aCx, 37 JS::Handle<JSObject*> aGivenProto) override; 38 NumberOfOutputs()39 uint16_t NumberOfOutputs() const final { return 0; } 40 41 uint32_t MaxChannelCount() const; 42 void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) override; 43 44 void Init(); 45 void Close(); 46 47 // Returns the track or null after unlink. 48 AudioNodeTrack* Track(); 49 50 void Mute(); 51 void Unmute(); 52 53 void Suspend(); 54 void Resume(); 55 56 void StartRendering(Promise* aPromise); 57 58 void OfflineShutdown(); 59 60 void NotifyMainThreadTrackEnded() override; 61 void FireOfflineCompletionEvent(); 62 NodeType()63 const char* NodeType() const override { return "AudioDestinationNode"; } 64 65 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override; 66 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override; 67 68 void NotifyDataAudibleStateChanged(bool aAudible); 69 void ResolvePromise(AudioBuffer* aRenderedBuffer); 70 Length()71 unsigned long Length() { 72 MOZ_ASSERT(mIsOffline); 73 return mFramesToProduce; 74 } 75 76 void NotifyAudioContextStateChanged(); 77 78 protected: 79 virtual ~AudioDestinationNode(); 80 81 private: 82 // This would be created for non-offline audio context in order to receive 83 // tab's mute/suspend/audio capture state change and update the audible state 84 // to the tab. 85 void CreateAndStartAudioChannelAgent(); 86 void DestroyAudioChannelAgentIfExists(); 87 RefPtr<AudioChannelAgent> mAudioChannelAgent; 88 89 // These members are related to audio capturing. We would start capturing 90 // audio if we're starting capturing audio from whole window, and MUST stop 91 // capturing explicitly when we don't need to capture audio any more, because 92 // we have to release the resource we allocated before. 93 bool IsCapturingAudio() const; 94 void StartAudioCapturingTrack(); 95 void StopAudioCapturingTrack(); 96 RefPtr<MediaInputPort> mCaptureTrackPort; 97 98 // These members are used to determine if the destination node is actual 99 // audible and `mFinalAudibleState` represents the final result. 100 using AudibleChangedReasons = AudioChannelService::AudibleChangedReasons; 101 using AudibleState = AudioChannelService::AudibleState; 102 void UpdateFinalAudibleStateIfNeeded(AudibleChangedReasons aReason); 103 bool IsAudible() const; 104 bool mFinalAudibleState = false; 105 bool mIsDataAudible = false; 106 float mAudioChannelVolume = 1.0; 107 108 // True if the audio channel disables the track for unvisited tab, and the 109 // track will be enabled again when the tab gets first visited, or a user 110 // presses the tab play icon. 111 bool mAudioChannelDisabled = false; 112 113 // When the destination node is audible, we would request a wakelock to 114 // prevent computer from sleeping in order to keep audio playing. 115 void CreateAudioWakeLockIfNeeded(); 116 void ReleaseAudioWakeLockIfExists(); 117 RefPtr<WakeLock> mWakeLock; 118 119 SelfReference<AudioDestinationNode> mOfflineRenderingRef; 120 uint32_t mFramesToProduce; 121 122 RefPtr<Promise> mOfflineRenderingPromise; 123 124 bool mIsOffline; 125 126 // These varaibles are used to know how long AudioContext would become audible 127 // since it was created. 128 TimeStamp mCreatedTime; 129 TimeDuration mDurationBeforeFirstTimeAudible; 130 }; 131 132 } // namespace dom 133 } // namespace mozilla 134 135 #endif 136