예제 #1
0
//==============================================================================
void Processor::prepareToPlay(double /*sampleRate*/, int samplesPerBlock)
{
  // Play safe to be clean
  releaseResources();

  // Prepare convolvers
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    _convolverHeadBlockSize = 1;
    while (_convolverHeadBlockSize < static_cast<size_t>(samplesPerBlock))
    {
      _convolverHeadBlockSize *= 2;
    }
    _convolverTailBlockSize = std::max(size_t(8192), 2 * _convolverHeadBlockSize);
  }

  // Prepare convolution buffers
  _wetBuffer.setSize(2, samplesPerBlock);
  _convolutionBuffer.resize(samplesPerBlock);

  // Initialize parameters
  _stereoWidth.initializeWidth(getParameter(Parameters::StereoWidth));

  // Initialize IR agents
  for (size_t i=0; i<_agents.size(); ++i)
  {
    _agents[i]->initialize();
  }

  notifyAboutChange();
  updateConvolvers();
}
예제 #2
0
void Processor::setIREnd(double irEnd)
{
  bool changed = false;
  bool irChanged = false;
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    double irEndClamped = std::min(1.0, std::max(_irBegin, irEnd));
    if (::fabs(irEndClamped-irEnd) > 0.0001)
    {
      changed = true;
    }
    if (::fabs(_irEnd-irEndClamped) > 0.0001)
    {
      _irEnd = irEndClamped;
      changed = true;
      irChanged = true;
    }    
  }
  if (changed)
  {
    notifyAboutChange();    
  }
  if (irChanged)
  {
    updateConvolvers();
  }
}
예제 #3
0
void Processor::setParameter(int index, float newValue)
{
  if (_parameterSet.setNormalizedParameter(index, newValue))
  {
    notifyAboutChange();
  }
}
예제 #4
0
void Processor::clearConvolvers()
{
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    _reverse = false;
    _predelayMs = 0.0;
    _stretch = 1.0;
    _irBegin = 0.0;
    _irEnd = 1.0;
    _attackLength = 0.0;
    _attackShape = 0.0;
    _decayShape = 0.0;
  }

  setParameterNotifyingHost(Parameters::EqLowCutFreq, Parameters::EqLowCutFreq.getDefaultValue());
  setParameterNotifyingHost(Parameters::EqLowShelfFreq, Parameters::EqLowShelfFreq.getDefaultValue());
  setParameterNotifyingHost(Parameters::EqLowShelfDecibels, Parameters::EqLowShelfDecibels.getDefaultValue());
  setParameterNotifyingHost(Parameters::EqHighCutFreq, Parameters::EqHighCutFreq.getDefaultValue());
  setParameterNotifyingHost(Parameters::EqHighShelfFreq, Parameters::EqHighShelfFreq.getDefaultValue());
  setParameterNotifyingHost(Parameters::EqHighShelfDecibels, Parameters::EqHighShelfDecibels.getDefaultValue());
  setParameterNotifyingHost(Parameters::StereoWidth, Parameters::StereoWidth.getDefaultValue());

  for (size_t i=0; i<_agents.size(); ++i)
  {
    _agents[i]->clear();
  }

  notifyAboutChange();
  updateConvolvers();
}
예제 #5
0
void Processor::releaseResources()
{
  _wetBuffer.setSize(1, 0, false, true, false);
  _convolutionBuffer.clear();
  _beatsPerMinute.set(0);
  notifyAboutChange();
}
예제 #6
0
void Processor::setPredelayMs(double predelayMs)
{
  bool changed = false;
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    if (_predelayMs != predelayMs)
    {
      _predelayMs = predelayMs;
      changed = true;
    }
  }
  if (changed)
  {
    notifyAboutChange();
    updateConvolvers();
  }
}
예제 #7
0
void Processor::setReverse(bool reverse)
{
  bool changed = false;
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    if (_reverse != reverse)
    {
      _reverse = reverse;
      changed = true;
    }
  }
  if (changed)
  {
    notifyAboutChange();
    updateConvolvers();
  }
}
예제 #8
0
void Processor::setStretch(double stretch)
{
  bool changed = false;
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    if (::fabs(_stretch-stretch) > 0.000001)
    {
      _stretch = stretch;
      changed = true;
    }
  }
  if (changed)
  {
    notifyAboutChange();
    updateConvolvers();
  }
}
예제 #9
0
void Processor::setDecayShape(double shape)
{
  bool changed = false;
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    if (_decayShape != shape)
    {
      _decayShape = shape;
      changed = true;
    }
  }
  if (changed)
  {
    notifyAboutChange();
    updateConvolvers();
  }
}
예제 #10
0
void Processor::setAttackLength(double length)
{
  bool changed = false;
  length = std::max(0.0, std::min(1.0, length));
  {
    juce::ScopedLock convolverLock(_convolverMutex);
    if (_attackLength != length)
    {
      _attackLength = length;
      changed = true;
    }
  }
  if (changed)
  {
    notifyAboutChange();
    updateConvolvers();
  }
}
예제 #11
0
void Processor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& /*midiMessages*/)
{ 
  const int numInputChannels = getTotalNumInputChannels();
  const int numOutputChannels = getTotalNumOutputChannels();
  const size_t samplesToProcess = buffer.getNumSamples();

  // Determine channel data
  const float* channelData0 = nullptr;
  const float* channelData1 = nullptr;
  if (numInputChannels == 1)
  {    
    channelData0 = buffer.getReadPointer(0);
    channelData1 = buffer.getReadPointer(0);
  }
  else if (numInputChannels == 2)
  {
    channelData0 = buffer.getReadPointer(0);
    channelData1 = buffer.getReadPointer(1);
  }

  // Convolution
  _wetBuffer.clear();
  if (numInputChannels > 0 && numOutputChannels > 0)
  {
    float autoGain = 1.0f;
    if (getParameter(Parameters::AutoGainOn))
    {
      autoGain = DecibelScaling::Db2Gain(getParameter(Parameters::AutoGainDecibels));
    }

    // Convolve
    IRAgent* irAgent00 = getAgent(0, 0);
    if (irAgent00 && irAgent00->getConvolver() && numInputChannels >= 1 && numOutputChannels >= 1)
    {
      irAgent00->process(channelData0, &_convolutionBuffer[0], samplesToProcess);
      _wetBuffer.addFrom(0, 0, &_convolutionBuffer[0], samplesToProcess, autoGain);
    }

    IRAgent* irAgent01 = getAgent(0, 1);
    if (irAgent01 && irAgent01->getConvolver() && numInputChannels >= 1 && numOutputChannels >= 2)
    {
      irAgent01->process(channelData0, &_convolutionBuffer[0], samplesToProcess);
      _wetBuffer.addFrom(1, 0, &_convolutionBuffer[0], samplesToProcess, autoGain);
    }

    IRAgent* irAgent10 = getAgent(1, 0);
    if (irAgent10 && irAgent10->getConvolver() && numInputChannels >= 2 && numOutputChannels >= 1)
    {      
      irAgent10->process(channelData1, &_convolutionBuffer[0], samplesToProcess);
      _wetBuffer.addFrom(0, 0, &_convolutionBuffer[0], samplesToProcess, autoGain);
    }

    IRAgent* irAgent11 = getAgent(1, 1);
    if (irAgent11 && irAgent11->getConvolver() && numInputChannels >= 2 && numOutputChannels >= 2)
    {
      irAgent11->process(channelData1, &_convolutionBuffer[0], samplesToProcess);
      _wetBuffer.addFrom(1, 0, &_convolutionBuffer[0], samplesToProcess, autoGain);
    }
  }

  // Stereo width
  if (numOutputChannels >= 2)
  {
    _stereoWidth.updateWidth(getParameter(Parameters::StereoWidth));
    _stereoWidth.process(_wetBuffer.getWritePointer(0), _wetBuffer.getWritePointer(1), samplesToProcess);
  }

  // Dry/wet gain
  {
    float dryGain0, dryGain1;
    _dryGain.updateValue(DecibelScaling::Db2Gain(getParameter(Parameters::DryDecibels)));
    _dryGain.getSmoothValues(samplesToProcess, dryGain0, dryGain1);
    buffer.applyGainRamp(0, samplesToProcess, dryGain0, dryGain1);
  }
  {
    float wetGain0, wetGain1;
    _wetGain.updateValue(DecibelScaling::Db2Gain(getParameter(Parameters::WetDecibels)));
    _wetGain.getSmoothValues(samplesToProcess, wetGain0, wetGain1);
    _wetBuffer.applyGainRamp(0, samplesToProcess, wetGain0, wetGain1);
  }

  // Level measurement (dry)
  if (numInputChannels == 1)
  {    
    _levelMeasurementsDry[0].process(samplesToProcess, buffer.getReadPointer(0));
    _levelMeasurementsDry[1].reset();
  }
  else if (numInputChannels == 2)
  {
    _levelMeasurementsDry[0].process(samplesToProcess, buffer.getReadPointer(0));
    _levelMeasurementsDry[1].process(samplesToProcess, buffer.getReadPointer(1));
  }

  // Sum wet to dry signal
  {
    float dryOnGain0, dryOnGain1;
    _dryOn.updateValue(getParameter(Parameters::DryOn) ? 1.0f : 0.0f);
    _dryOn.getSmoothValues(samplesToProcess, dryOnGain0, dryOnGain1);
    buffer.applyGainRamp(0, samplesToProcess, dryOnGain0, dryOnGain1);
  }
  {
    float wetOnGain0, wetOnGain1;
    _wetOn.updateValue(getParameter(Parameters::WetOn) ? 1.0f : 0.0f);
    _wetOn.getSmoothValues(samplesToProcess, wetOnGain0, wetOnGain1);
    if (numOutputChannels > 0)
    {
      buffer.addFromWithRamp(0, 0, _wetBuffer.getReadPointer(0), samplesToProcess, wetOnGain0, wetOnGain1);
    }
    if (numOutputChannels > 1)
    {
      buffer.addFromWithRamp(1, 0, _wetBuffer.getReadPointer(1), samplesToProcess, wetOnGain0, wetOnGain1);
    }
  }

  // Level measurement (wet/out)
  if (numOutputChannels == 1)
  {
    _levelMeasurementsWet[0].process(samplesToProcess, _wetBuffer.getReadPointer(0));
    _levelMeasurementsWet[1].reset();
    _levelMeasurementsOut[0].process(samplesToProcess, buffer.getReadPointer(0));
    _levelMeasurementsOut[1].reset();
  }
  else if (numOutputChannels == 2)
  {
    _levelMeasurementsWet[0].process(samplesToProcess, _wetBuffer.getReadPointer(0));
    _levelMeasurementsWet[1].process(samplesToProcess, _wetBuffer.getReadPointer(1));
    _levelMeasurementsOut[0].process(samplesToProcess, buffer.getReadPointer(0));
    _levelMeasurementsOut[1].process(samplesToProcess, buffer.getReadPointer(1));
  }

  // In case we have more outputs than inputs, we'll clear any output
  // channels that didn't contain input data, (because these aren't
  // guaranteed to be empty - they may contain garbage).
  for (int i=numInputChannels; i<numOutputChannels; ++i)
  {
    buffer.clear(i, 0, buffer.getNumSamples());
  }

  // Update beats per minute info
  float beatsPerMinute = 0.0f;
  juce::AudioPlayHead* playHead = getPlayHead();
  if (playHead)
  {
    juce::AudioPlayHead::CurrentPositionInfo currentPositionInfo;
    if (playHead->getCurrentPosition(currentPositionInfo))
    {
      beatsPerMinute = static_cast<float>(currentPositionInfo.bpm);
    }
  }
  if (::fabs(_beatsPerMinute.exchange(beatsPerMinute)-beatsPerMinute) > 0.001f)
  {
    notifyAboutChange();
  }
}
예제 #12
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setReadOnly(const bool& value) {
    readOnly_ = value;
    notifyObserversOnSetReadOnly(readOnly_);
    notifyAboutChange();
}
예제 #13
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setDisplayName(const std::string& displayName) {
    displayName_ = displayName;
    notifyObserversOnSetDisplayName(displayName_);
    notifyAboutChange();
}
예제 #14
0
void Processor::numChannelsChanged()
{
  juce::AudioProcessor::numChannelsChanged();
  notifyAboutChange();
}
예제 #15
0
void IRAgent::propagateChange()
{
  notifyAboutChange();
  _processor.notifyAboutChange();
}
예제 #16
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setVisible(bool val) {
    visible_ = val;
    notifyObserversOnSetVisible(visible_);
    notifyAboutChange();
}
예제 #17
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setUsageMode(UsageMode usageMode) {
    usageMode_ = usageMode;
    notifyObserversOnSetUsageMode(usageMode_);
    notifyAboutChange();
}
예제 #18
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setIdentifier(const std::string& identifier) {
    identifier_ = identifier;
    notifyObserversOnSetIdentifier(identifier_);
    notifyAboutChange();
}
예제 #19
0
파일: property.cpp 프로젝트: Ojaswi/inviwo
void Property::setSemantics(const PropertySemantics& semantics) {
    semantics_ = semantics;
    notifyObserversOnSetSemantics(semantics_);
    notifyAboutChange();
}