LCOV - code coverage report
Current view: top level - dom/media/webaudio - ConstantSourceNode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 124 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          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 "ConstantSourceNode.h"
       8             : 
       9             : #include "AudioDestinationNode.h"
      10             : #include "nsContentUtils.h"
      11             : 
      12             : namespace mozilla {
      13             : namespace dom {
      14             : 
      15           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(ConstantSourceNode, AudioScheduledSourceNode,
      16             :                                    mOffset)
      17             : 
      18           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ConstantSourceNode)
      19           0 : NS_INTERFACE_MAP_END_INHERITING(AudioScheduledSourceNode)
      20             : 
      21           0 : NS_IMPL_ADDREF_INHERITED(ConstantSourceNode, AudioScheduledSourceNode)
      22           0 : NS_IMPL_RELEASE_INHERITED(ConstantSourceNode, AudioScheduledSourceNode)
      23             : 
      24           0 : class ConstantSourceNodeEngine final : public AudioNodeEngine
      25             : {
      26             : public:
      27           0 :   ConstantSourceNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)
      28           0 :     : AudioNodeEngine(aNode)
      29             :     , mSource(nullptr)
      30           0 :     , mDestination(aDestination->Stream())
      31             :     , mStart(-1)
      32             :     , mStop(STREAM_TIME_MAX)
      33             :     // Keep the default values in sync with ConstantSourceNode::ConstantSourceNode.
      34           0 :     , mOffset(1.0f)
      35             :   {
      36           0 :     MOZ_ASSERT(NS_IsMainThread());
      37           0 :   }
      38             : 
      39           0 :   void SetSourceStream(AudioNodeStream* aSource)
      40             :   {
      41           0 :     mSource = aSource;
      42           0 :   }
      43             : 
      44             :   enum Parameters {
      45             :     OFFSET,
      46             :     START,
      47             :     STOP,
      48             :   };
      49           0 :   void RecvTimelineEvent(uint32_t aIndex,
      50             :                          AudioTimelineEvent& aEvent) override
      51             :   {
      52           0 :     MOZ_ASSERT(mDestination);
      53             : 
      54           0 :     WebAudioUtils::ConvertAudioTimelineEventToTicks(aEvent,
      55           0 :                                                     mDestination);
      56             : 
      57           0 :     switch (aIndex) {
      58             :     case OFFSET:
      59           0 :       mOffset.InsertEvent<int64_t>(aEvent);
      60           0 :       break;
      61             :     default:
      62           0 :       NS_ERROR("Bad ConstantSourceNodeEngine TimelineParameter");
      63             :     }
      64           0 :   }
      65             : 
      66           0 :   void SetStreamTimeParameter(uint32_t aIndex, StreamTime aParam) override
      67             :   {
      68           0 :     switch (aIndex) {
      69             :     case START:
      70           0 :       mStart = aParam;
      71           0 :       mSource->SetActive();
      72           0 :       break;
      73           0 :     case STOP: mStop = aParam; break;
      74             :     default:
      75           0 :       NS_ERROR("Bad ConstantSourceNodeEngine StreamTimeParameter");
      76             :     }
      77           0 :   }
      78             : 
      79           0 :   void ProcessBlock(AudioNodeStream* aStream,
      80             :                     GraphTime aFrom,
      81             :                     const AudioBlock& aInput,
      82             :                     AudioBlock* aOutput,
      83             :                     bool* aFinished) override
      84             :   {
      85           0 :     MOZ_ASSERT(mSource == aStream, "Invalid source stream");
      86             : 
      87           0 :     StreamTime ticks = mDestination->GraphTimeToStreamTime(aFrom);
      88           0 :     if (mStart == -1) {
      89           0 :       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      90           0 :       return;
      91             :     }
      92             : 
      93           0 :     if (ticks + WEBAUDIO_BLOCK_SIZE <= mStart || ticks >= mStop) {
      94           0 :       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      95             :     } else {
      96           0 :       aOutput->AllocateChannels(1);
      97           0 :       float* output = aOutput->ChannelFloatsForWrite(0);
      98             : 
      99           0 :       if (mOffset.HasSimpleValue()) {
     100           0 :         for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
     101           0 :           output[i] = mOffset.GetValueAtTime(aFrom, 0);
     102             :         }
     103             :       } else {
     104           0 :         mOffset.GetValuesAtTime(ticks, output, WEBAUDIO_BLOCK_SIZE);
     105             :       }
     106             :     }
     107             : 
     108           0 :     if (ticks + WEBAUDIO_BLOCK_SIZE >= mStop) {
     109             :       // We've finished playing.
     110           0 :       *aFinished = true;
     111             :     }
     112             :   }
     113             : 
     114           0 :   bool IsActive() const override
     115             :   {
     116             :     // start() has been called.
     117           0 :     return mStart != -1;
     118             :   }
     119             : 
     120           0 :   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
     121             :   {
     122           0 :     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     123             : 
     124             :     // Not owned:
     125             :     // - mSource
     126             :     // - mDestination
     127             :     // - mOffset (internal ref owned by node)
     128             : 
     129           0 :     return amount;
     130             :   }
     131             : 
     132           0 :   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
     133             :   {
     134           0 :     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     135             :   }
     136             : 
     137             :   AudioNodeStream* mSource;
     138             :   AudioNodeStream* mDestination;
     139             :   StreamTime mStart;
     140             :   StreamTime mStop;
     141             :   AudioParamTimeline mOffset;
     142             : };
     143             : 
     144           0 : ConstantSourceNode::ConstantSourceNode(AudioContext* aContext)
     145             :   : AudioScheduledSourceNode(aContext,
     146             :                              1,
     147             :                              ChannelCountMode::Max,
     148             :                              ChannelInterpretation::Speakers)
     149             :   , mOffset(new AudioParam(this, ConstantSourceNodeEngine::OFFSET,
     150           0 :                            "offset", 1.0f))
     151           0 :   , mStartCalled(false)
     152             : {
     153           0 :   ConstantSourceNodeEngine* engine = new ConstantSourceNodeEngine(this, aContext->Destination());
     154           0 :   mStream = AudioNodeStream::Create(aContext, engine,
     155             :                                     AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
     156           0 :                                     aContext->Graph());
     157           0 :   engine->SetSourceStream(mStream);
     158           0 :   mStream->AddMainThreadListener(this);
     159           0 : }
     160             : 
     161           0 : ConstantSourceNode::~ConstantSourceNode()
     162             : {
     163           0 : }
     164             : 
     165             : size_t
     166           0 : ConstantSourceNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
     167             : {
     168           0 :   size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
     169             : 
     170           0 :   amount += mOffset->SizeOfIncludingThis(aMallocSizeOf);
     171           0 :   return amount;
     172             : }
     173             : 
     174             : size_t
     175           0 : ConstantSourceNode::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
     176             : {
     177           0 :   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     178             : }
     179             : 
     180             : JSObject*
     181           0 : ConstantSourceNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     182             : {
     183           0 :   return ConstantSourceNodeBinding::Wrap(aCx, this, aGivenProto);
     184             : }
     185             : 
     186             : already_AddRefed<ConstantSourceNode>
     187           0 : ConstantSourceNode::Constructor(const GlobalObject& aGlobal,
     188             :                                 AudioContext& aContext,
     189             :                                 const ConstantSourceOptions& aOptions,
     190             :                                 ErrorResult& aRv)
     191             : {
     192           0 :   RefPtr<ConstantSourceNode> object = new ConstantSourceNode(&aContext);
     193           0 :   object->mOffset->SetValue(aOptions.mOffset);
     194           0 :   return object.forget();
     195             : }
     196             : 
     197             : void
     198           0 : ConstantSourceNode::DestroyMediaStream()
     199             : {
     200           0 :   if (mStream) {
     201           0 :     mStream->RemoveMainThreadListener(this);
     202             :   }
     203           0 :   AudioNode::DestroyMediaStream();
     204           0 : }
     205             : 
     206             : void
     207           0 : ConstantSourceNode::Start(double aWhen, ErrorResult& aRv)
     208             : {
     209           0 :   if (!WebAudioUtils::IsTimeValid(aWhen)) {
     210           0 :     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     211           0 :     return;
     212             :   }
     213             : 
     214           0 :   if (mStartCalled) {
     215           0 :     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     216           0 :     return;
     217             :   }
     218           0 :   mStartCalled = true;
     219             : 
     220           0 :   if (!mStream) {
     221           0 :     return;
     222             :   }
     223             : 
     224           0 :   mStream->SetStreamTimeParameter(ConstantSourceNodeEngine::START,
     225           0 :                                   Context(), aWhen);
     226             : 
     227           0 :   MarkActive();
     228             : }
     229             : 
     230             : void
     231           0 : ConstantSourceNode::Stop(double aWhen, ErrorResult& aRv)
     232             : {
     233           0 :   if (!WebAudioUtils::IsTimeValid(aWhen)) {
     234           0 :     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     235           0 :     return;
     236             :   }
     237             : 
     238           0 :   if (!mStartCalled) {
     239           0 :     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     240           0 :     return;
     241             :   }
     242             : 
     243           0 :   if (!mStream || !Context()) {
     244           0 :     return;
     245             :   }
     246             : 
     247           0 :   mStream->SetStreamTimeParameter(ConstantSourceNodeEngine::STOP,
     248           0 :                                   Context(), std::max(0.0, aWhen));
     249             : }
     250             : 
     251             : void
     252           0 : ConstantSourceNode::NotifyMainThreadStreamFinished()
     253             : {
     254           0 :   MOZ_ASSERT(mStream->IsFinished());
     255             : 
     256           0 :   class EndedEventDispatcher final : public Runnable
     257             :   {
     258             :   public:
     259           0 :     explicit EndedEventDispatcher(ConstantSourceNode* aNode)
     260           0 :       : mozilla::Runnable("EndedEventDispatcher")
     261           0 :       , mNode(aNode)
     262             :     {
     263           0 :     }
     264           0 :     NS_IMETHOD Run() override
     265             :     {
     266             :       // If it's not safe to run scripts right now, schedule this to run later
     267           0 :       if (!nsContentUtils::IsSafeToRunScript()) {
     268           0 :         nsContentUtils::AddScriptRunner(this);
     269           0 :         return NS_OK;
     270             :       }
     271             : 
     272           0 :       mNode->DispatchTrustedEvent(NS_LITERAL_STRING("ended"));
     273             :       // Release stream resources.
     274           0 :       mNode->DestroyMediaStream();
     275           0 :       return NS_OK;
     276             :     }
     277             :   private:
     278             :     RefPtr<ConstantSourceNode> mNode;
     279             :   };
     280             : 
     281           0 :   Context()->Dispatch(do_AddRef(new EndedEventDispatcher(this)));
     282             : 
     283             :   // Drop the playing reference
     284             :   // Warning: The below line might delete this.
     285           0 :   MarkInactive();
     286           0 : }
     287             : 
     288             : } // namespace dom
     289             : } // namespace mozilla

Generated by: LCOV version 1.13