LCOV - code coverage report
Current view: top level - dom/media/webaudio - DynamicsCompressorNode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 106 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 22 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 "DynamicsCompressorNode.h"
       8             : #include "mozilla/dom/DynamicsCompressorNodeBinding.h"
       9             : #include "nsAutoPtr.h"
      10             : #include "AudioNodeEngine.h"
      11             : #include "AudioNodeStream.h"
      12             : #include "AudioDestinationNode.h"
      13             : #include "WebAudioUtils.h"
      14             : #include "blink/DynamicsCompressor.h"
      15             : 
      16             : using WebCore::DynamicsCompressor;
      17             : 
      18             : namespace mozilla {
      19             : namespace dom {
      20             : 
      21           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(DynamicsCompressorNode, AudioNode,
      22             :                                    mThreshold,
      23             :                                    mKnee,
      24             :                                    mRatio,
      25             :                                    mAttack,
      26             :                                    mRelease)
      27             : 
      28           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DynamicsCompressorNode)
      29           0 : NS_INTERFACE_MAP_END_INHERITING(AudioNode)
      30             : 
      31           0 : NS_IMPL_ADDREF_INHERITED(DynamicsCompressorNode, AudioNode)
      32           0 : NS_IMPL_RELEASE_INHERITED(DynamicsCompressorNode, AudioNode)
      33             : 
      34           0 : class DynamicsCompressorNodeEngine final : public AudioNodeEngine
      35             : {
      36             : public:
      37           0 :   explicit DynamicsCompressorNodeEngine(AudioNode* aNode,
      38             :                                         AudioDestinationNode* aDestination)
      39           0 :     : AudioNodeEngine(aNode)
      40           0 :     , mDestination(aDestination->Stream())
      41             :     // Keep the default value in sync with the default value in
      42             :     // DynamicsCompressorNode::DynamicsCompressorNode.
      43             :     , mThreshold(-24.f)
      44             :     , mKnee(30.f)
      45             :     , mRatio(12.f)
      46             :     , mAttack(0.003f)
      47             :     , mRelease(0.25f)
      48           0 :     , mCompressor(new DynamicsCompressor(mDestination->SampleRate(), 2))
      49             :   {
      50           0 :   }
      51             : 
      52             :   enum Parameters {
      53             :     THRESHOLD,
      54             :     KNEE,
      55             :     RATIO,
      56             :     ATTACK,
      57             :     RELEASE
      58             :   };
      59           0 :   void RecvTimelineEvent(uint32_t aIndex,
      60             :                          AudioTimelineEvent& aEvent) override
      61             :   {
      62           0 :     MOZ_ASSERT(mDestination);
      63             : 
      64           0 :     WebAudioUtils::ConvertAudioTimelineEventToTicks(aEvent,
      65           0 :                                                     mDestination);
      66             : 
      67           0 :     switch (aIndex) {
      68             :     case THRESHOLD:
      69           0 :       mThreshold.InsertEvent<int64_t>(aEvent);
      70           0 :       break;
      71             :     case KNEE:
      72           0 :       mKnee.InsertEvent<int64_t>(aEvent);
      73           0 :       break;
      74             :     case RATIO:
      75           0 :       mRatio.InsertEvent<int64_t>(aEvent);
      76           0 :       break;
      77             :     case ATTACK:
      78           0 :       mAttack.InsertEvent<int64_t>(aEvent);
      79           0 :       break;
      80             :     case RELEASE:
      81           0 :       mRelease.InsertEvent<int64_t>(aEvent);
      82           0 :       break;
      83             :     default:
      84           0 :       NS_ERROR("Bad DynamicsCompresssorNodeEngine TimelineParameter");
      85             :     }
      86           0 :   }
      87             : 
      88           0 :   void ProcessBlock(AudioNodeStream* aStream,
      89             :                     GraphTime aFrom,
      90             :                     const AudioBlock& aInput,
      91             :                     AudioBlock* aOutput,
      92             :                     bool* aFinished) override
      93             :   {
      94           0 :     if (aInput.IsNull()) {
      95             :       // Just output silence
      96           0 :       *aOutput = aInput;
      97           0 :       return;
      98             :     }
      99             : 
     100           0 :     const uint32_t channelCount = aInput.ChannelCount();
     101           0 :     if (mCompressor->numberOfChannels() != channelCount) {
     102             :       // Create a new compressor object with a new channel count
     103           0 :       mCompressor = new WebCore::DynamicsCompressor(aStream->SampleRate(),
     104           0 :                                                     aInput.ChannelCount());
     105             :     }
     106             : 
     107           0 :     StreamTime pos = mDestination->GraphTimeToStreamTime(aFrom);
     108           0 :     mCompressor->setParameterValue(DynamicsCompressor::ParamThreshold,
     109           0 :                                    mThreshold.GetValueAtTime(pos));
     110           0 :     mCompressor->setParameterValue(DynamicsCompressor::ParamKnee,
     111           0 :                                    mKnee.GetValueAtTime(pos));
     112           0 :     mCompressor->setParameterValue(DynamicsCompressor::ParamRatio,
     113           0 :                                    mRatio.GetValueAtTime(pos));
     114           0 :     mCompressor->setParameterValue(DynamicsCompressor::ParamAttack,
     115           0 :                                    mAttack.GetValueAtTime(pos));
     116           0 :     mCompressor->setParameterValue(DynamicsCompressor::ParamRelease,
     117           0 :                                    mRelease.GetValueAtTime(pos));
     118             : 
     119           0 :     aOutput->AllocateChannels(channelCount);
     120           0 :     mCompressor->process(&aInput, aOutput, aInput.GetDuration());
     121             : 
     122           0 :     SendReductionParamToMainThread(aStream,
     123           0 :                                    mCompressor->parameterValue(DynamicsCompressor::ParamReduction));
     124             :   }
     125             : 
     126           0 :   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
     127             :   {
     128             :     // Not owned:
     129             :     // - mDestination (probably)
     130             :     // - Don't count the AudioParamTimelines, their inner refs are owned by the
     131             :     // AudioNode.
     132           0 :     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     133           0 :     amount += mCompressor->sizeOfIncludingThis(aMallocSizeOf);
     134           0 :     return amount;
     135             :   }
     136             : 
     137           0 :   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
     138             :   {
     139           0 :     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     140             :   }
     141             : 
     142             : private:
     143           0 :   void SendReductionParamToMainThread(AudioNodeStream* aStream, float aReduction)
     144             :   {
     145           0 :     MOZ_ASSERT(!NS_IsMainThread());
     146             : 
     147           0 :     class Command final : public Runnable
     148             :     {
     149             :     public:
     150           0 :       Command(AudioNodeStream* aStream, float aReduction)
     151           0 :         : mozilla::Runnable("Command")
     152             :         , mStream(aStream)
     153           0 :         , mReduction(aReduction)
     154             :       {
     155           0 :       }
     156             : 
     157           0 :       NS_IMETHOD Run() override
     158             :       {
     159             :         RefPtr<DynamicsCompressorNode> node =
     160             :           static_cast<DynamicsCompressorNode*>
     161           0 :             (mStream->Engine()->NodeMainThread());
     162           0 :         if (node) {
     163           0 :           node->SetReduction(mReduction);
     164             :         }
     165           0 :         return NS_OK;
     166             :       }
     167             : 
     168             :     private:
     169             :       RefPtr<AudioNodeStream> mStream;
     170             :       float mReduction;
     171             :     };
     172             : 
     173           0 :     mAbstractMainThread->Dispatch(do_AddRef(new Command(aStream, aReduction)));
     174           0 :   }
     175             : 
     176             : private:
     177             :   AudioNodeStream* mDestination;
     178             :   AudioParamTimeline mThreshold;
     179             :   AudioParamTimeline mKnee;
     180             :   AudioParamTimeline mRatio;
     181             :   AudioParamTimeline mAttack;
     182             :   AudioParamTimeline mRelease;
     183             :   nsAutoPtr<DynamicsCompressor> mCompressor;
     184             : };
     185             : 
     186           0 : DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
     187             :   : AudioNode(aContext,
     188             :               2,
     189             :               ChannelCountMode::Explicit,
     190             :               ChannelInterpretation::Speakers)
     191             :   , mThreshold(new AudioParam(this, DynamicsCompressorNodeEngine::THRESHOLD,
     192           0 :                               "threshold", -24.f, -100.f, 0.f))
     193             :   , mKnee(new AudioParam(this, DynamicsCompressorNodeEngine::KNEE,
     194           0 :                          "knee", 30.f, 0.f, 40.f))
     195             :   , mRatio(new AudioParam(this, DynamicsCompressorNodeEngine::RATIO,
     196           0 :                           "ratio", 12.f, 1.f, 20.f))
     197             :   , mReduction(0)
     198             :   , mAttack(new AudioParam(this, DynamicsCompressorNodeEngine::ATTACK,
     199           0 :                            "attack", 0.003f, 0.f, 1.f))
     200             :   , mRelease(new AudioParam(this, DynamicsCompressorNodeEngine::RELEASE,
     201           0 :                             "release", 0.25f, 0.f, 1.f))
     202             : {
     203           0 :   DynamicsCompressorNodeEngine* engine = new DynamicsCompressorNodeEngine(this, aContext->Destination());
     204           0 :   mStream = AudioNodeStream::Create(aContext, engine,
     205             :                                     AudioNodeStream::NO_STREAM_FLAGS,
     206           0 :                                     aContext->Graph());
     207           0 : }
     208             : 
     209             : /* static */ already_AddRefed<DynamicsCompressorNode>
     210           0 : DynamicsCompressorNode::Create(AudioContext& aAudioContext,
     211             :                                const DynamicsCompressorOptions& aOptions,
     212             :                                ErrorResult& aRv)
     213             : {
     214           0 :   if (aAudioContext.CheckClosed(aRv)) {
     215           0 :     return nullptr;
     216             :   }
     217             : 
     218             :   RefPtr<DynamicsCompressorNode> audioNode =
     219           0 :     new DynamicsCompressorNode(&aAudioContext);
     220             : 
     221           0 :   audioNode->Initialize(aOptions, aRv);
     222           0 :   if (NS_WARN_IF(aRv.Failed())) {
     223           0 :     return nullptr;
     224             :   }
     225             : 
     226           0 :   audioNode->Attack()->SetValue(aOptions.mAttack);
     227           0 :   audioNode->Knee()->SetValue(aOptions.mKnee);
     228           0 :   audioNode->Ratio()->SetValue(aOptions.mRatio);
     229           0 :   audioNode->GetRelease()->SetValue(aOptions.mRelease);
     230           0 :   audioNode->Threshold()->SetValue(aOptions.mThreshold);
     231             : 
     232           0 :   return audioNode.forget();
     233             : }
     234             : 
     235             : size_t
     236           0 : DynamicsCompressorNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
     237             : {
     238           0 :   size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
     239           0 :   amount += mThreshold->SizeOfIncludingThis(aMallocSizeOf);
     240           0 :   amount += mKnee->SizeOfIncludingThis(aMallocSizeOf);
     241           0 :   amount += mRatio->SizeOfIncludingThis(aMallocSizeOf);
     242           0 :   amount += mAttack->SizeOfIncludingThis(aMallocSizeOf);
     243           0 :   amount += mRelease->SizeOfIncludingThis(aMallocSizeOf);
     244           0 :   return amount;
     245             : }
     246             : 
     247             : size_t
     248           0 : DynamicsCompressorNode::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
     249             : {
     250           0 :   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     251             : }
     252             : 
     253             : JSObject*
     254           0 : DynamicsCompressorNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     255             : {
     256           0 :   return DynamicsCompressorNodeBinding::Wrap(aCx, this, aGivenProto);
     257             : }
     258             : 
     259             : } // namespace dom
     260             : } // namespace mozilla

Generated by: LCOV version 1.13