mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 864091 - Part 3: Implement DynamicsCompressorNode's processing based on the Blink's implementation; r=padenot
This commit is contained in:
parent
f03533b4a7
commit
27c7c4dcf7
@ -201,6 +201,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void CancelAllEvents()
|
||||
{
|
||||
mEvents.Clear();
|
||||
}
|
||||
|
||||
// This method computes the AudioParam value at a given time based on the event timeline
|
||||
template<class TimeType>
|
||||
float GetValueAtTime(TimeType aTime) const
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include "AudioNodeStream.h"
|
||||
#include "AudioDestinationNode.h"
|
||||
#include "WebAudioUtils.h"
|
||||
#include "blink/DynamicsCompressor.h"
|
||||
|
||||
using WebCore::DynamicsCompressor;
|
||||
|
||||
const unsigned DEFAULT_NUMBER_OF_CHANNELS = 2;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -41,9 +46,10 @@ public:
|
||||
, mThreshold(-24.f)
|
||||
, mKnee(30.f)
|
||||
, mRatio(12.f)
|
||||
, mReduction(0.f)
|
||||
, mAttack(0.003f)
|
||||
, mRelease(0.25f)
|
||||
, mCompressor(new DynamicsCompressor(aNode->Context()->SampleRate(),
|
||||
DEFAULT_NUMBER_OF_CHANNELS))
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,7 +62,6 @@ public:
|
||||
THRESHOLD,
|
||||
KNEE,
|
||||
RATIO,
|
||||
REDUCTION,
|
||||
ATTACK,
|
||||
RELEASE
|
||||
};
|
||||
@ -76,10 +81,6 @@ public:
|
||||
mRatio = aValue;
|
||||
WebAudioUtils::ConvertAudioParamToTicks(mRatio, mSource, mDestination);
|
||||
break;
|
||||
case REDUCTION:
|
||||
mReduction = aValue;
|
||||
WebAudioUtils::ConvertAudioParamToTicks(mReduction, mSource, mDestination);
|
||||
break;
|
||||
case ATTACK:
|
||||
mAttack = aValue;
|
||||
WebAudioUtils::ConvertAudioParamToTicks(mAttack, mSource, mDestination);
|
||||
@ -98,8 +99,62 @@ public:
|
||||
AudioChunk* aOutput,
|
||||
bool* aFinished) MOZ_OVERRIDE
|
||||
{
|
||||
// TODO: do the necessary computation here
|
||||
*aOutput = aInput;
|
||||
if (aInput.IsNull()) {
|
||||
// Just output silence
|
||||
*aOutput = aInput;
|
||||
return;
|
||||
}
|
||||
|
||||
TrackTicks pos = aStream->GetCurrentPosition();
|
||||
mCompressor->setParameterValue(DynamicsCompressor::ParamThreshold,
|
||||
mThreshold.GetValueAtTime(pos));
|
||||
mCompressor->setParameterValue(DynamicsCompressor::ParamKnee,
|
||||
mKnee.GetValueAtTime(pos));
|
||||
mCompressor->setParameterValue(DynamicsCompressor::ParamRatio,
|
||||
mRatio.GetValueAtTime(pos));
|
||||
mCompressor->setParameterValue(DynamicsCompressor::ParamAttack,
|
||||
mAttack.GetValueAtTime(pos));
|
||||
mCompressor->setParameterValue(DynamicsCompressor::ParamRelease,
|
||||
mRelease.GetValueAtTime(pos));
|
||||
|
||||
AllocateAudioBlock(DEFAULT_NUMBER_OF_CHANNELS, aOutput);
|
||||
mCompressor->process(&aInput, aOutput, aInput.GetDuration());
|
||||
|
||||
SendReductionParamToMainThread(aStream,
|
||||
mCompressor->parameterValue(DynamicsCompressor::ParamReduction));
|
||||
}
|
||||
|
||||
private:
|
||||
void SendReductionParamToMainThread(AudioNodeStream* aStream, float aReduction)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
class Command : public nsRunnable
|
||||
{
|
||||
public:
|
||||
Command(AudioNodeStream* aStream, float aReduction)
|
||||
: mStream(aStream)
|
||||
, mReduction(aReduction)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
nsRefPtr<DynamicsCompressorNode> node = static_cast<DynamicsCompressorNode*>(mStream->Engine()->Node());
|
||||
if (node) {
|
||||
AudioParam* reduction = node->Reduction();
|
||||
reduction->CancelAllEvents();
|
||||
reduction->SetValue(mReduction);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<AudioNodeStream> mStream;
|
||||
float mReduction;
|
||||
};
|
||||
|
||||
NS_DispatchToMainThread(new Command(aStream, aReduction));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -108,9 +163,9 @@ private:
|
||||
AudioParamTimeline mThreshold;
|
||||
AudioParamTimeline mKnee;
|
||||
AudioParamTimeline mRatio;
|
||||
AudioParamTimeline mReduction;
|
||||
AudioParamTimeline mAttack;
|
||||
AudioParamTimeline mRelease;
|
||||
nsAutoPtr<DynamicsCompressor> mCompressor;
|
||||
};
|
||||
|
||||
DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
|
||||
@ -118,12 +173,13 @@ DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
|
||||
, mThreshold(new AudioParam(this, SendThresholdToStream, -24.f))
|
||||
, mKnee(new AudioParam(this, SendKneeToStream, 30.f))
|
||||
, mRatio(new AudioParam(this, SendRatioToStream, 12.f))
|
||||
, mReduction(new AudioParam(this, SendReductionToStream, 0.f))
|
||||
, mReduction(new AudioParam(this, Callback, 0.f))
|
||||
, mAttack(new AudioParam(this, SendAttackToStream, 0.003f))
|
||||
, mRelease(new AudioParam(this, SendReleaseToStream, 0.25f))
|
||||
{
|
||||
DynamicsCompressorNodeEngine* engine = new DynamicsCompressorNodeEngine(this, aContext->Destination());
|
||||
mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
|
||||
mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM,
|
||||
DEFAULT_NUMBER_OF_CHANNELS);
|
||||
engine->SetSourceStream(static_cast<AudioNodeStream*> (mStream.get()));
|
||||
}
|
||||
|
||||
@ -154,13 +210,6 @@ DynamicsCompressorNode::SendRatioToStream(AudioNode* aNode)
|
||||
SendTimelineParameterToStream(This, DynamicsCompressorNodeEngine::RATIO, *This->mRatio);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicsCompressorNode::SendReductionToStream(AudioNode* aNode)
|
||||
{
|
||||
DynamicsCompressorNode* This = static_cast<DynamicsCompressorNode*>(aNode);
|
||||
SendTimelineParameterToStream(This, DynamicsCompressorNodeEngine::REDUCTION, *This->mReduction);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicsCompressorNode::SendAttackToStream(AudioNode* aNode)
|
||||
{
|
||||
|
@ -65,7 +65,6 @@ private:
|
||||
static void SendThresholdToStream(AudioNode* aNode);
|
||||
static void SendKneeToStream(AudioNode* aNode);
|
||||
static void SendRatioToStream(AudioNode* aNode);
|
||||
static void SendReductionToStream(AudioNode* aNode);
|
||||
static void SendAttackToStream(AudioNode* aNode);
|
||||
static void SendReleaseToStream(AudioNode* aNode);
|
||||
|
||||
|
@ -213,6 +213,8 @@ void TestEventRemoval()
|
||||
is(timeline.GetEventCount(), 3u, "Should successfully delete one event");
|
||||
timeline.CancelScheduledValues(0.12);
|
||||
is(timeline.GetEventCount(), 1u, "Should successfully delete two events");
|
||||
timeline.CancelAllEvents();
|
||||
ok(timeline.HasSimpleValue(), "No event should remain scheduled");
|
||||
}
|
||||
|
||||
void TestBeforeFirstEventSetValue()
|
||||
|
Loading…
Reference in New Issue
Block a user