| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE 6 technical preview.
 -    Copyright (c) 2020 - Raw Material Software Limited
 - 
 -    You may use this code under the terms of the GPL v3
 -    (see www.gnu.org/licenses).
 - 
 -    For this technical preview, this file is not subject to commercial licensing.
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - namespace juce
 - {
 - 
 - SamplerSound::SamplerSound (const String& soundName,
 -                             AudioFormatReader& source,
 -                             const BigInteger& notes,
 -                             int midiNoteForNormalPitch,
 -                             double attackTimeSecs,
 -                             double releaseTimeSecs,
 -                             double maxSampleLengthSeconds)
 -     : name (soundName),
 -       sourceSampleRate (source.sampleRate),
 -       midiNotes (notes),
 -       midiRootNote (midiNoteForNormalPitch)
 - {
 -     if (sourceSampleRate > 0 && source.lengthInSamples > 0)
 -     {
 -         length = jmin ((int) source.lengthInSamples,
 -                        (int) (maxSampleLengthSeconds * sourceSampleRate));
 - 
 -         data.reset (new AudioBuffer<float> (jmin (2, (int) source.numChannels), length + 4));
 - 
 -         source.read (data.get(), 0, length + 4, 0, true, true);
 - 
 -         params.attack  = static_cast<float> (attackTimeSecs);
 -         params.release = static_cast<float> (releaseTimeSecs);
 -     }
 - }
 - 
 - SamplerSound::~SamplerSound()
 - {
 - }
 - 
 - bool SamplerSound::appliesToNote (int midiNoteNumber)
 - {
 -     return midiNotes[midiNoteNumber];
 - }
 - 
 - bool SamplerSound::appliesToChannel (int /*midiChannel*/)
 - {
 -     return true;
 - }
 - 
 - //==============================================================================
 - SamplerVoice::SamplerVoice() {}
 - SamplerVoice::~SamplerVoice() {}
 - 
 - bool SamplerVoice::canPlaySound (SynthesiserSound* sound)
 - {
 -     return dynamic_cast<const SamplerSound*> (sound) != nullptr;
 - }
 - 
 - void SamplerVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSound* s, int /*currentPitchWheelPosition*/)
 - {
 -     if (auto* sound = dynamic_cast<const SamplerSound*> (s))
 -     {
 -         pitchRatio = std::pow (2.0, (midiNoteNumber - sound->midiRootNote) / 12.0)
 -                         * sound->sourceSampleRate / getSampleRate();
 - 
 -         sourceSamplePosition = 0.0;
 -         lgain = velocity;
 -         rgain = velocity;
 - 
 -         adsr.setSampleRate (sound->sourceSampleRate);
 -         adsr.setParameters (sound->params);
 - 
 -         adsr.noteOn();
 -     }
 -     else
 -     {
 -         jassertfalse; // this object can only play SamplerSounds!
 -     }
 - }
 - 
 - void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff)
 - {
 -     if (allowTailOff)
 -     {
 -         adsr.noteOff();
 -     }
 -     else
 -     {
 -         clearCurrentNote();
 -         adsr.reset();
 -     }
 - }
 - 
 - void SamplerVoice::pitchWheelMoved (int /*newValue*/) {}
 - void SamplerVoice::controllerMoved (int /*controllerNumber*/, int /*newValue*/) {}
 - 
 - //==============================================================================
 - void SamplerVoice::renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
 - {
 -     if (auto* playingSound = static_cast<SamplerSound*> (getCurrentlyPlayingSound().get()))
 -     {
 -         auto& data = *playingSound->data;
 -         const float* const inL = data.getReadPointer (0);
 -         const float* const inR = data.getNumChannels() > 1 ? data.getReadPointer (1) : nullptr;
 - 
 -         float* outL = outputBuffer.getWritePointer (0, startSample);
 -         float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getWritePointer (1, startSample) : nullptr;
 - 
 -         while (--numSamples >= 0)
 -         {
 -             auto pos = (int) sourceSamplePosition;
 -             auto alpha = (float) (sourceSamplePosition - pos);
 -             auto invAlpha = 1.0f - alpha;
 - 
 -             // just using a very simple linear interpolation here..
 -             float l = (inL[pos] * invAlpha + inL[pos + 1] * alpha);
 -             float r = (inR != nullptr) ? (inR[pos] * invAlpha + inR[pos + 1] * alpha)
 -                                        : l;
 - 
 -             auto envelopeValue = adsr.getNextSample();
 - 
 -             l *= lgain * envelopeValue;
 -             r *= rgain * envelopeValue;
 - 
 -             if (outR != nullptr)
 -             {
 -                 *outL++ += l;
 -                 *outR++ += r;
 -             }
 -             else
 -             {
 -                 *outL++ += (l + r) * 0.5f;
 -             }
 - 
 -             sourceSamplePosition += pitchRatio;
 - 
 -             if (sourceSamplePosition > playingSound->length)
 -             {
 -                 stopNote (0.0f, false);
 -                 break;
 -             }
 -         }
 -     }
 - }
 - 
 - } // namespace juce
 
 
  |