33 int midiNoteForNormalPitch,
34 double attackTimeSecs,
35 double releaseTimeSecs,
36 double maxSampleLengthSeconds)
38 sourceSampleRate (source.sampleRate),
40 midiRootNote (midiNoteForNormalPitch)
45 (
int) (maxSampleLengthSeconds * sourceSampleRate));
49 source.
read (data.get(), 0, length + 4, 0,
true,
true);
51 params.
attack =
static_cast<float> (attackTimeSecs);
52 params.
release =
static_cast<float> (releaseTimeSecs);
62 return midiNotes[midiNoteNumber];
76 return dynamic_cast<const SamplerSound*
> (sound) !=
nullptr;
81 if (
auto* sound = dynamic_cast<const SamplerSound*> (s))
83 pitchRatio = std::pow (2.0, (midiNoteNumber - sound->midiRootNote) / 12.0)
84 * sound->sourceSampleRate / getSampleRate();
86 sourceSamplePosition = 0.0;
90 adsr.setSampleRate (sound->sourceSampleRate);
91 adsr.setParameters (sound->params);
120 if (
auto* playingSound = static_cast<SamplerSound*> (getCurrentlyPlayingSound().
get()))
122 auto& data = *playingSound->data;
123 const float*
const inL = data.getReadPointer (0);
124 const float*
const inR = data.getNumChannels() > 1 ? data.getReadPointer (1) :
nullptr;
129 while (--numSamples >= 0)
131 auto pos = (int) sourceSamplePosition;
132 auto alpha = (float) (sourceSamplePosition - pos);
133 auto invAlpha = 1.0f - alpha;
136 float l = (inL[pos] * invAlpha + inL[pos + 1] * alpha);
137 float r = (inR !=
nullptr) ? (inR[pos] * invAlpha + inR[pos + 1] * alpha)
140 auto envelopeValue = adsr.getNextSample();
142 l *= lgain * envelopeValue;
143 r *= rgain * envelopeValue;
152 *outL++ += (l + r) * 0.5f;
155 sourceSamplePosition += pitchRatio;
157 if (sourceSamplePosition > playingSound->length)
159 stopNote (0.0f,
false);
SamplerSound(const String &name, AudioFormatReader &source, const BigInteger &midiNotes, int midiNoteForNormalPitch, double attackTimeSecs, double releaseTimeSecs, double maxSampleLengthSeconds)
Creates a sampled sound from an audio reader.
~SamplerSound() override
Destructor.
float attack
Attack time in seconds.
float release
Release time in seconds.
bool canPlaySound(SynthesiserSound *) override
Must return true if this voice object is capable of playing the given sound.
void pitchWheelMoved(int newValue) override
Called to let the voice know that the pitch wheel has been moved.
Describes one of the sounds that a Synthesiser can play.
An arbitrarily large integer class.
void stopNote(float velocity, bool allowTailOff) override
Called to stop a note.
int getNumChannels() const noexcept
Returns the number of channels of audio data that this buffer contains.
~SamplerVoice() override
Destructor.
void controllerMoved(int controllerNumber, int newValue) override
Called to let the voice know that a midi controller has been moved.
void startNote(int midiNoteNumber, float velocity, SynthesiserSound *, int pitchWheel) override
Called to start a new note.
bool appliesToChannel(int midiChannel) override
Returns true if the sound should be triggered by midi events on a given channel.
bool appliesToNote(int midiNoteNumber) override
Returns true if this sound should be played when a given midi note is pressed.
Type * getWritePointer(int channelNumber) noexcept
Returns a writeable pointer to one of the buffer's channels.
A subclass of SynthesiserSound that represents a sampled audio clip.
SamplerVoice()
Creates a SamplerVoice.
void renderNextBlock(AudioBuffer< float > &, int startSample, int numSamples) override
Renders the next block of data for this voice.