content/media/webaudio/AudioParam.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     7 #include "AudioParam.h"
     8 #include "mozilla/dom/AudioParamBinding.h"
     9 #include "AudioNodeEngine.h"
    10 #include "AudioNodeStream.h"
    11 #include "AudioContext.h"
    13 namespace mozilla {
    14 namespace dom {
    16 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioParam)
    18 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioParam)
    19   tmp->DisconnectFromGraphAndDestroyStream();
    20   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNode)
    21   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    22 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioParam)
    24   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode)
    25   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
    26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    28 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioParam)
    30 NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(AudioParam)
    32 NS_IMETHODIMP_(MozExternalRefCountType)
    33 AudioParam::Release()
    34 {
    35   if (mRefCnt.get() == 1) {
    36     // We are about to be deleted, disconnect the object from the graph before
    37     // the derived type is destroyed.
    38     DisconnectFromGraphAndDestroyStream();
    39   }
    40   NS_IMPL_CC_NATIVE_RELEASE_BODY(AudioParam)
    41 }
    43 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioParam, AddRef)
    44 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioParam, Release)
    46 AudioParam::AudioParam(AudioNode* aNode,
    47                        AudioParam::CallbackType aCallback,
    48                        float aDefaultValue)
    49   : AudioParamTimeline(aDefaultValue)
    50   , mNode(aNode)
    51   , mCallback(aCallback)
    52   , mDefaultValue(aDefaultValue)
    53 {
    54   SetIsDOMBinding();
    55 }
    57 AudioParam::~AudioParam()
    58 {
    59   MOZ_ASSERT(mInputNodes.IsEmpty());
    60 }
    62 JSObject*
    63 AudioParam::WrapObject(JSContext* aCx)
    64 {
    65   return AudioParamBinding::Wrap(aCx, this);
    66 }
    68 void
    69 AudioParam::DisconnectFromGraphAndDestroyStream()
    70 {
    71   // Addref this temporarily so the refcount bumping below doesn't destroy us
    72   // prematurely
    73   nsRefPtr<AudioParam> kungFuDeathGrip = this;
    75   while (!mInputNodes.IsEmpty()) {
    76     uint32_t i = mInputNodes.Length() - 1;
    77     nsRefPtr<AudioNode> input = mInputNodes[i].mInputNode;
    78     mInputNodes.RemoveElementAt(i);
    79     input->RemoveOutputParam(this);
    80   }
    82   if (mNodeStreamPort) {
    83     mNodeStreamPort->Destroy();
    84     mNodeStreamPort = nullptr;
    85   }
    87   if (mStream) {
    88     mStream->Destroy();
    89     mStream = nullptr;
    90   }
    91 }
    93 MediaStream*
    94 AudioParam::Stream()
    95 {
    96   if (mStream) {
    97     return mStream;
    98   }
   100   AudioNodeEngine* engine = new AudioNodeEngine(nullptr);
   101   nsRefPtr<AudioNodeStream> stream =
   102     mNode->Context()->Graph()->CreateAudioNodeStream(engine,
   103                                                      MediaStreamGraph::INTERNAL_STREAM,
   104                                                      Node()->Context()->SampleRate());
   106   // Force the input to have only one channel, and make it down-mix using
   107   // the speaker rules if needed.
   108   stream->SetChannelMixingParametersImpl(1, ChannelCountMode::Explicit, ChannelInterpretation::Speakers);
   109   // Mark as an AudioParam helper stream
   110   stream->SetAudioParamHelperStream();
   112   mStream = stream.forget();
   114   // Setup the AudioParam's stream as an input to the owner AudioNode's stream
   115   MediaStream* nodeStream = mNode->Stream();
   116   MOZ_ASSERT(nodeStream->AsProcessedStream());
   117   ProcessedMediaStream* ps = static_cast<ProcessedMediaStream*>(nodeStream);
   118   mNodeStreamPort = ps->AllocateInputPort(mStream, MediaInputPort::FLAG_BLOCK_INPUT);
   120   // Let the MSG's copy of AudioParamTimeline know about the change in the stream
   121   mCallback(mNode);
   123   return mStream;
   124 }
   126 float
   127 AudioParamTimeline::AudioNodeInputValue(size_t aCounter) const
   128 {
   129   MOZ_ASSERT(mStream);
   131   // If we have a chunk produced by the AudioNode inputs to the AudioParam,
   132   // get its value now.  We use aCounter to tell us which frame of the last
   133   // AudioChunk to look at.
   134   float audioNodeInputValue = 0.0f;
   135   const AudioChunk& lastAudioNodeChunk =
   136     static_cast<AudioNodeStream*>(mStream.get())->LastChunks()[0];
   137   if (!lastAudioNodeChunk.IsNull()) {
   138     MOZ_ASSERT(lastAudioNodeChunk.GetDuration() == WEBAUDIO_BLOCK_SIZE);
   139     audioNodeInputValue =
   140       static_cast<const float*>(lastAudioNodeChunk.mChannelData[0])[aCounter];
   141     audioNodeInputValue *= lastAudioNodeChunk.mVolume;
   142   }
   144   return audioNodeInputValue;
   145 }
   147 }
   148 }

mercurial