mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-22 03:43:58 +00:00
Bug 875277 - Part 1: Implement WaveShaperNode.oversample - webidl enums. r=ehsan
This commit is contained in:
parent
e0561e8097
commit
835d56c5d5
@ -41,14 +41,51 @@ class WaveShaperNodeEngine : public AudioNodeEngine
|
||||
public:
|
||||
explicit WaveShaperNodeEngine(AudioNode* aNode)
|
||||
: AudioNodeEngine(aNode)
|
||||
, mType(OverSampleType::None)
|
||||
{
|
||||
}
|
||||
|
||||
enum Parameteres {
|
||||
TYPE
|
||||
};
|
||||
|
||||
virtual void SetRawArrayData(nsTArray<float>& aCurve) MOZ_OVERRIDE
|
||||
{
|
||||
mCurve.SwapElements(aCurve);
|
||||
}
|
||||
|
||||
virtual void SetInt32Parameter(uint32_t aIndex, int32_t aValue) MOZ_OVERRIDE
|
||||
{
|
||||
switch (aIndex) {
|
||||
case TYPE:
|
||||
mType = static_cast<OverSampleType>(aValue);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Bad WaveShaperNode Int32Parameter");
|
||||
}
|
||||
}
|
||||
|
||||
template <uint32_t blocks>
|
||||
void ProcessCurve(const float* aInputBuffer, float* aOutputBuffer)
|
||||
{
|
||||
for (uint32_t j = 0; j < WEBAUDIO_BLOCK_SIZE*blocks; ++j) {
|
||||
// Index into the curve array based on the amplitude of the
|
||||
// incoming signal by clamping the amplitude to [-1, 1] and
|
||||
// performing a linear interpolation of the neighbor values.
|
||||
float index = std::max(0.0f, std::min(float(mCurve.Length() - 1),
|
||||
mCurve.Length() * (aInputBuffer[j] + 1) / 2));
|
||||
uint32_t indexLower = uint32_t(index);
|
||||
uint32_t indexHigher = uint32_t(index + 1.0f);
|
||||
if (indexHigher == mCurve.Length()) {
|
||||
aOutputBuffer[j] = mCurve[indexLower];
|
||||
} else {
|
||||
float interpolationFactor = index - indexLower;
|
||||
aOutputBuffer[j] = (1.0f - interpolationFactor) * mCurve[indexLower] +
|
||||
interpolationFactor * mCurve[indexHigher];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ProduceAudioBlock(AudioNodeStream* aStream,
|
||||
const AudioChunk& aInput,
|
||||
AudioChunk* aOutput,
|
||||
@ -66,27 +103,26 @@ public:
|
||||
for (uint32_t i = 0; i < channelCount; ++i) {
|
||||
const float* inputBuffer = static_cast<const float*>(aInput.mChannelData[i]);
|
||||
float* outputBuffer = const_cast<float*> (static_cast<const float*>(aOutput->mChannelData[i]));
|
||||
for (uint32_t j = 0; j < WEBAUDIO_BLOCK_SIZE; ++j) {
|
||||
// Index into the curve array based on the amplitude of the
|
||||
// incoming signal by clamping the amplitude to [-1, 1] and
|
||||
// performing a linear interpolation of the neighbor values.
|
||||
float index = std::max(0.0f, std::min(float(mCurve.Length() - 1),
|
||||
mCurve.Length() * (inputBuffer[j] + 1) / 2));
|
||||
uint32_t indexLower = uint32_t(index);
|
||||
uint32_t indexHigher = uint32_t(index + 1.0f);
|
||||
if (indexHigher == mCurve.Length()) {
|
||||
outputBuffer[j] = mCurve[indexLower];
|
||||
} else {
|
||||
float interpolationFactor = index - indexLower;
|
||||
outputBuffer[j] = (1.0f - interpolationFactor) * mCurve[indexLower] +
|
||||
interpolationFactor * mCurve[indexHigher];
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case OverSampleType::None:
|
||||
ProcessCurve<1>(inputBuffer, outputBuffer);
|
||||
break;
|
||||
case OverSampleType::_2x:
|
||||
/* TODO: to be implemented */
|
||||
break;
|
||||
case OverSampleType::_4x:
|
||||
/* TODO: to be implemented */
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("We should never reach here");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<float> mCurve;
|
||||
OverSampleType mType;
|
||||
};
|
||||
|
||||
WaveShaperNode::WaveShaperNode(AudioContext* aContext)
|
||||
@ -95,6 +131,7 @@ WaveShaperNode::WaveShaperNode(AudioContext* aContext)
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mCurve(nullptr)
|
||||
, mType(OverSampleType::None)
|
||||
{
|
||||
NS_HOLD_JS_OBJECTS(this, WaveShaperNode);
|
||||
|
||||
@ -138,5 +175,12 @@ WaveShaperNode::SetCurve(const Nullable<Float32Array>& aCurve)
|
||||
ns->SetRawArrayData(curve);
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::SetOversample(OverSampleType aType)
|
||||
{
|
||||
mType = aType;
|
||||
SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE, static_cast<int32_t>(aType));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "AudioNode.h"
|
||||
#include "AudioParam.h"
|
||||
#include "mozilla/dom/WaveShaperNodeBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -33,6 +34,12 @@ public:
|
||||
}
|
||||
void SetCurve(const Nullable<Float32Array>& aData);
|
||||
|
||||
OverSampleType Oversample() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
void SetOversample(OverSampleType aType);
|
||||
|
||||
private:
|
||||
void ClearCurve();
|
||||
|
||||
|
@ -10,10 +10,17 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
enum OverSampleType {
|
||||
"none",
|
||||
"2x",
|
||||
"4x"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface WaveShaperNode : AudioNode {
|
||||
|
||||
attribute Float32Array? curve;
|
||||
attribute OverSampleType oversample;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user