void
AudioBufferSourceNode::SendLoopParametersToStream()
{
  // Don't compute and set the loop parameters unnecessarily
  if (mLoop && mBuffer) {
    float rate = mBuffer->SampleRate();
    double length = (double(mBuffer->Length()) / mBuffer->SampleRate());
    double actualLoopStart, actualLoopEnd;
    if (mLoopStart >= 0.0 && mLoopEnd > 0.0 &&
        mLoopStart < mLoopEnd) {
      MOZ_ASSERT(mLoopStart != 0.0 || mLoopEnd != 0.0);
      actualLoopStart = (mLoopStart > length) ? 0.0 : mLoopStart;
      actualLoopEnd = std::min(mLoopEnd, length);
    } else {
      actualLoopStart = 0.0;
      actualLoopEnd = length;
    }
    int32_t loopStartTicks = NS_lround(actualLoopStart * rate);
    int32_t loopEndTicks = NS_lround(actualLoopEnd * rate);
    if (loopStartTicks < loopEndTicks) {
      SendInt32ParameterToStream(LOOPSTART, loopStartTicks);
      SendInt32ParameterToStream(LOOPEND, loopEndTicks);
      SendInt32ParameterToStream(LOOP, 1);
    } else {
      // Be explicit about looping not happening if the offsets make
      // looping impossible.
      SendInt32ParameterToStream(LOOP, 0);
    }
  } else if (!mLoop) {
    SendInt32ParameterToStream(LOOP, 0);
  }
}
void
AudioBufferSourceNode::SendLoopParametersToStream()
{
  // Don't compute and set the loop parameters unnecessarily
  if (mLoop && mBuffer) {
    float rate = mBuffer->SampleRate();
    double length = (double(mBuffer->Length()) / mBuffer->SampleRate());
    double actualLoopStart, actualLoopEnd;
    if (((mLoopStart != 0.0) || (mLoopEnd != 0.0)) &&
        mLoopStart >= 0.0 && mLoopEnd > 0.0 &&
        mLoopStart < mLoopEnd) {
      actualLoopStart = (mLoopStart > length) ? 0.0 : mLoopStart;
      actualLoopEnd = std::min(mLoopEnd, length);
    } else {
      actualLoopStart = 0.0;
      actualLoopEnd = length;
    }
    int32_t loopStartTicks = NS_lround(actualLoopStart * rate);
    int32_t loopEndTicks = NS_lround(actualLoopEnd * rate);
    if (loopStartTicks < loopEndTicks) {
      SendInt32ParameterToStream(LOOPSTART, loopStartTicks);
      SendInt32ParameterToStream(LOOPEND, loopEndTicks);
      SendInt32ParameterToStream(LOOP, 1);
    }
  } else if (!mLoop) {
    SendInt32ParameterToStream(LOOP, 0);
  }
}
Beispiel #3
0
void
WaveShaperNode::SetOversample(OverSampleType aType)
{
  mType = aType;
  SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE,
                             static_cast<int32_t>(aType));
}
void
BiquadFilterNode::SetType(BiquadFilterType aType)
{
  mType = aType;
  SendInt32ParameterToStream(BiquadFilterNodeEngine::TYPE,
                             static_cast<int32_t>(aType));
}
Beispiel #5
0
void
OscillatorNode::SendTypeToStream()
{
  if (mType == OscillatorType::Custom) {
    // The engine assumes we'll send the custom data before updating the type.
    SendPeriodicWaveToStream();
  }
  SendInt32ParameterToStream(OscillatorNodeEngine::TYPE, static_cast<int32_t>(mType));
}
Beispiel #6
0
void
BiquadFilterNode::SetType(uint16_t aType, ErrorResult& aRv)
{
    BiquadTypeEnum type = static_cast<BiquadTypeEnum> (aType);
    if (type > BiquadTypeEnum::Max) {
        aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    } else {
        mType = type;
        SendInt32ParameterToStream(BiquadFilterNodeEngine::TYPE, aType);
    }
}
Beispiel #7
0
void OscillatorNode::SendPeriodicWaveToStream()
{
  NS_ASSERTION(mType == OscillatorType::Custom,
               "Sending custom waveform to engine thread with non-custom type");
  MOZ_ASSERT(mStream, "Missing node stream.");
  MOZ_ASSERT(mPeriodicWave, "Send called without PeriodicWave object.");
  SendInt32ParameterToStream(OscillatorNodeEngine::PERIODICWAVE,
                             mPeriodicWave->DataLength());
  nsRefPtr<ThreadSharedFloatArrayBufferList> data =
    mPeriodicWave->GetThreadSharedBuffer();
  mStream->SetBuffer(data.forget());
}
Beispiel #8
0
void
ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv)
{
    if (aBuffer) {
        switch (aBuffer->NumberOfChannels()) {
        case 1:
        case 2:
        case 4:
            // Supported number of channels
            break;
        default:
            aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
            return;
        }
    }

    mBuffer = aBuffer;

    // Send the buffer to the stream
    AudioNodeStream* ns = static_cast<AudioNodeStream*>(mStream.get());
    MOZ_ASSERT(ns, "Why don't we have a stream here?");
    if (mBuffer) {
        uint32_t length = mBuffer->Length();
        nsRefPtr<ThreadSharedFloatArrayBufferList> data =
            mBuffer->GetThreadSharedChannelsForRate(aCx);
        if (data && length < WEBAUDIO_BLOCK_SIZE) {
            // For very small impulse response buffers, we need to pad the
            // buffer with 0 to make sure that the Reverb implementation
            // has enough data to compute FFTs from.
            length = WEBAUDIO_BLOCK_SIZE;
            nsRefPtr<ThreadSharedFloatArrayBufferList> paddedBuffer =
                new ThreadSharedFloatArrayBufferList(data->GetChannels());
            float* channelData = (float*) malloc(sizeof(float) * length * data->GetChannels());
            for (uint32_t i = 0; i < data->GetChannels(); ++i) {
                PodCopy(channelData + length * i, data->GetData(i), mBuffer->Length());
                PodZero(channelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length());
                paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, channelData);
            }
            data = paddedBuffer;
        }
        SendInt32ParameterToStream(ConvolverNodeEngine::BUFFER_LENGTH, length);
        SendDoubleParameterToStream(ConvolverNodeEngine::SAMPLE_RATE,
                                    mBuffer->SampleRate());
        ns->SetBuffer(data.forget());
    } else {
        ns->SetBuffer(nullptr);
    }
}
void
ScriptProcessorNode::UpdateConnectedStatus()
{
  bool isConnected = mHasPhantomInput ||
    !(OutputNodes().IsEmpty() && OutputParams().IsEmpty()
      && InputNodes().IsEmpty());

  // Events are queued even when there is no listener because a listener
  // may be added while events are in the queue.
  SendInt32ParameterToStream(ScriptProcessorNodeEngine::IS_CONNECTED,
                             isConnected);

  if (isConnected && HasListenersFor(nsGkAtoms::onaudioprocess)) {
    MarkActive();
  } else {
    MarkInactive();
  }
}
void
BiquadFilterNode::SetType(BiquadFilterType aType)
{
  // Handle the alternate enum values
  switch (aType) {
  case BiquadFilterType::_0: aType = BiquadFilterType::Lowpass; break;
  case BiquadFilterType::_1: aType = BiquadFilterType::Highpass; break;
  case BiquadFilterType::_2: aType = BiquadFilterType::Bandpass; break;
  case BiquadFilterType::_3: aType = BiquadFilterType::Lowshelf; break;
  case BiquadFilterType::_4: aType = BiquadFilterType::Highshelf; break;
  case BiquadFilterType::_5: aType = BiquadFilterType::Peaking; break;
  case BiquadFilterType::_6: aType = BiquadFilterType::Notch; break;
  case BiquadFilterType::_7: aType = BiquadFilterType::Allpass; break;
  default:
    // Shut up the compiler warning
    break;
  }

  mType = aType;
  SendInt32ParameterToStream(BiquadFilterNodeEngine::TYPE,
                             static_cast<int32_t>(aType));
}
void
AudioDestinationNode::Resume()
{
  CreateAudioChannelAgent();
  SendInt32ParameterToStream(DestinationNodeEngine::SUSPENDED, 0);
}
void
AudioDestinationNode::Suspend()
{
  DestroyAudioChannelAgent();
  SendInt32ParameterToStream(DestinationNodeEngine::SUSPENDED, 1);
}
Beispiel #13
0
void
ConvolverNode::SetNormalize(bool aNormalize)
{
    mNormalize = aNormalize;
    SendInt32ParameterToStream(ConvolverNodeEngine::NORMALIZE, aNormalize);
}