Commit 7b02c4de authored by Karl Tomlinson's avatar Karl Tomlinson
Browse files

bug 1480661 use single precision for operating on delay values r=padenot

These are derived from single precision AudioParam values
and so there is little to gain from using double.

double has the disadvantage that values intended to be integer
frame counts are less likely to be integer. e.g.

(rr) print ((float)(128.0/48000.0))*48000.f
$91 = 128
(rr) print ((float)(128.0/48000.0))*48000.0
$92 = 127.99999862909317
(rr) print ((float)(128.0/44100.0))*44100.f
$93 = 128
(rr) print ((float)(128.0/44100.0))*44100.0
$94 = 127.99999765120447
(rr) print ((float)(768.0/48000.0))*48000.f
$95 = 768.000061
(rr) print ((float)(768.0/48000.0))*48000.0
$96 = 768.0000364780426
(rr) print ((float)(768.0/44100.0))*44100.f
$97 = 768
(rr) print ((float)(768.0/44100.0))*44100.0
$98 = 768.00002697855234

MozReview-Commit-ID: FlmZJeBjUYY

--HG--
extra : rebase_source : 5c4f4a68383468c6afd15de43526eae42b01154b
parent db85c1ab
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ DelayBuffer::Write(const AudioBlock& aInputChunk)
}

void
DelayBuffer::Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
DelayBuffer::Read(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
                  AudioBlock* aOutputChunk,
                  ChannelInterpretation aChannelInterpretation)
{
@@ -63,8 +63,8 @@ DelayBuffer::Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
  // First find the range of "delay" offsets backwards from the current
  // position.  Note that these may be negative for frames that are after the
  // current position (including i).
  double minDelay = aPerFrameDelays[0];
  double maxDelay = minDelay;
  float minDelay = aPerFrameDelays[0];
  float maxDelay = minDelay;
  for (unsigned i = 1; i < WEBAUDIO_BLOCK_SIZE; ++i) {
    minDelay = std::min(minDelay, aPerFrameDelays[i] - i);
    maxDelay = std::max(maxDelay, aPerFrameDelays[i] - i);
@@ -93,7 +93,7 @@ DelayBuffer::Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
}

void
DelayBuffer::ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
DelayBuffer::ReadChannel(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
                         AudioBlock* aOutputChunk, uint32_t aChannel,
                         ChannelInterpretation aChannelInterpretation)
{
@@ -108,7 +108,7 @@ DelayBuffer::ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
}

void
DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
DelayBuffer::ReadChannels(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
                          AudioBlock* aOutputChunk,
                          uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
                          ChannelInterpretation aChannelInterpretation)
@@ -127,7 +127,7 @@ DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
  }

  for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
    double currentDelay = aPerFrameDelays[i];
    float currentDelay = aPerFrameDelays[i];
    MOZ_ASSERT(currentDelay >= 0.0);
    MOZ_ASSERT(currentDelay <= (mChunks.Length() - 1) * WEBAUDIO_BLOCK_SIZE);

@@ -136,7 +136,7 @@ DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
    // Use the larger delay, for the older frame, first, as this is more
    // likely to use the cached upmixed channel arrays.
    int floorDelay = int(currentDelay);
    double interpolationFactor = currentDelay - floorDelay;
    float interpolationFactor = currentDelay - floorDelay;
    int positions[2];
    positions[1] = PositionForDelay(floorDelay) + i;
    positions[0] = positions[1] - 1;
@@ -152,7 +152,7 @@ DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
        int readOffset = OffsetForPosition(positions[tick]);
        UpdateUpmixChannels(readChunk, totalChannelCount,
                            aChannelInterpretation);
        double multiplier = interpolationFactor * mChunks[readChunk].mVolume;
        float multiplier = interpolationFactor * mChunks[readChunk].mVolume;
        for (uint32_t channel = aFirstChannel;
             channel < readChannelsEnd; ++channel) {
          aOutputChunk->ChannelFloatsForWrite(channel)[i] += multiplier *
@@ -166,10 +166,10 @@ DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
}

void
DelayBuffer::Read(double aDelayTicks, AudioBlock* aOutputChunk,
DelayBuffer::Read(float aDelayTicks, AudioBlock* aOutputChunk,
                  ChannelInterpretation aChannelInterpretation)
{
  double computedDelay[WEBAUDIO_BLOCK_SIZE];
  float computedDelay[WEBAUDIO_BLOCK_SIZE];

  for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
    computedDelay[i] = aDelayTicks;
+6 −6
Original line number Diff line number Diff line
@@ -19,9 +19,9 @@ class DelayBuffer final
  typedef dom::ChannelInterpretation ChannelInterpretation;

public:
  explicit DelayBuffer(double aMaxDelayTicks)
  explicit DelayBuffer(float aMaxDelayTicks)
    // Round the maximum delay up to the next tick.
    : mMaxDelayTicks(ceil(aMaxDelayTicks))
    : mMaxDelayTicks(std::ceil(aMaxDelayTicks))
    , mCurrentChunk(0)
    // mLastReadChunk is initialized in EnsureBuffer
#ifdef DEBUG
@@ -40,19 +40,19 @@ public:

  // Read a block with an array of delays, in ticks, for each sample frame.
  // Each delay should be >= 0 and <= MaxDelayTicks().
  void Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
  void Read(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
            AudioBlock* aOutputChunk,
            ChannelInterpretation aChannelInterpretation);
  // Read a block with a constant delay. The delay should be >= 0 and
  // <= MaxDelayTicks().
  void Read(double aDelayTicks, AudioBlock* aOutputChunk,
  void Read(float aDelayTicks, AudioBlock* aOutputChunk,
            ChannelInterpretation aChannelInterpretation);

  // Read into one of the channels of aOutputChunk, given an array of
  // delays in ticks.  This is useful when delays are different on different
  // channels.  aOutputChunk must have already been allocated with at least as
  // many channels as were in any of the blocks passed to Write().
  void ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
  void ReadChannel(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
                   AudioBlock* aOutputChunk, uint32_t aChannel,
                   ChannelInterpretation aChannelInterpretation);

@@ -75,7 +75,7 @@ public:
  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;

private:
  void ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
  void ReadChannels(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
                    AudioBlock* aOutputChunk,
                    uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
                    ChannelInterpretation aChannelInterpretation);
+11 −11
Original line number Diff line number Diff line
@@ -30,14 +30,14 @@ class DelayNodeEngine final : public AudioNodeEngine
  typedef PlayingRefChangeHandler PlayingRefChanged;
public:
  DelayNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination,
                  double aMaxDelayTicks)
                  float aMaxDelayTicks)
    : AudioNodeEngine(aNode)
    , mDestination(aDestination->Stream())
    // Keep the default value in sync with the default value in DelayNode::DelayNode.
    , mDelay(0.f)
    // Use a smoothing range of 20ms
    , mBuffer(std::max(aMaxDelayTicks,
                       static_cast<double>(WEBAUDIO_BLOCK_SIZE)))
                       static_cast<float>(WEBAUDIO_BLOCK_SIZE)))
    , mMaxDelay(aMaxDelayTicks)
    , mHaveProducedBeforeInput(false)
    , mLeftOverData(INT32_MIN)
@@ -115,17 +115,17 @@ public:
  }

  void UpdateOutputBlock(AudioNodeStream* aStream, GraphTime aFrom,
                         AudioBlock* aOutput, double minDelay)
                         AudioBlock* aOutput, float minDelay)
  {
    double maxDelay = mMaxDelay;
    double sampleRate = aStream->SampleRate();
    float maxDelay = mMaxDelay;
    float sampleRate = aStream->SampleRate();
    ChannelInterpretation channelInterpretation =
      aStream->GetChannelInterpretation();
    if (mDelay.HasSimpleValue()) {
      // If this DelayNode is in a cycle, make sure the delay value is at least
      // one block, even if that is greater than maxDelay.
      double delayFrames = mDelay.GetValue() * sampleRate;
      double delayFramesClamped =
      float delayFrames = mDelay.GetValue() * sampleRate;
      float delayFramesClamped =
        std::max(minDelay, std::min(delayFrames, maxDelay));
      mBuffer.Read(delayFramesClamped, aOutput, channelInterpretation);
    } else {
@@ -136,10 +136,10 @@ public:
      float values[WEBAUDIO_BLOCK_SIZE];
      mDelay.GetValuesAtTime(tick, values,WEBAUDIO_BLOCK_SIZE);

      double computedDelay[WEBAUDIO_BLOCK_SIZE];
      float computedDelay[WEBAUDIO_BLOCK_SIZE];
      for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
        double delayAtTick = values[counter] * sampleRate;
        double delayAtTickClamped =
        float delayAtTick = values[counter] * sampleRate;
        float delayAtTickClamped =
          std::max(minDelay, std::min(delayAtTick, maxDelay));
        computedDelay[counter] = delayAtTickClamped;
      }
@@ -182,7 +182,7 @@ public:
  RefPtr<AudioNodeStream> mDestination;
  AudioParamTimeline mDelay;
  DelayBuffer mBuffer;
  double mMaxDelay;
  float mMaxDelay;
  bool mHaveProducedBeforeInput;
  // How much data we have in our buffer which needs to be flushed out when our inputs
  // finish.
+3 −3
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ namespace WebCore {

// The value of 2 milliseconds is larger than the largest delay which exists in any HRTFKernel from the default HRTFDatabase (0.0136 seconds).
// We ASSERT the delay values used in process() with this value.
const double MaxDelayTimeSeconds = 0.002;
const float MaxDelayTimeSeconds = 0.002;

const int UninitializedAzimuth = -1;
const unsigned RenderingQuantum = WEBAUDIO_BLOCK_SIZE;
@@ -220,8 +220,8 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBlock*
    MOZ_ASSERT(frameDelayL2 / sampleRate() < MaxDelayTimeSeconds && frameDelayR2 / sampleRate() < MaxDelayTimeSeconds);

    // Crossfade inter-aural delays based on transitions.
    double frameDelaysL[WEBAUDIO_BLOCK_SIZE];
    double frameDelaysR[WEBAUDIO_BLOCK_SIZE];
    float frameDelaysL[WEBAUDIO_BLOCK_SIZE];
    float frameDelaysR[WEBAUDIO_BLOCK_SIZE];
    {
      float x = m_crossfadeX;
      float incr = m_crossfadeIncr;