JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_Sampler.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30 AudioFormatReader& source,
31 const BigInteger& notes,
33 double attackTimeSecs,
34 double releaseTimeSecs,
36 : name (soundName),
37 sourceSampleRate (source.sampleRate),
38 midiNotes (notes),
39 midiRootNote (midiNoteForNormalPitch)
40{
41 if (sourceSampleRate > 0 && source.lengthInSamples > 0)
42 {
43 length = jmin ((int) source.lengthInSamples,
44 (int) (maxSampleLengthSeconds * sourceSampleRate));
45
46 data.reset (new AudioBuffer<float> (jmin (2, (int) source.numChannels), length + 4));
47
48 source.read (data.get(), 0, length + 4, 0, true, true);
49
50 params.attack = static_cast<float> (attackTimeSecs);
51 params.release = static_cast<float> (releaseTimeSecs);
52 }
53}
54
58
60{
61 return midiNotes[midiNoteNumber];
62}
63
64bool SamplerSound::appliesToChannel (int /*midiChannel*/)
65{
66 return true;
67}
68
69//==============================================================================
72
74{
75 return dynamic_cast<const SamplerSound*> (sound) != nullptr;
76}
77
78void SamplerVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSound* s, int /*currentPitchWheelPosition*/)
79{
80 if (auto* sound = dynamic_cast<const SamplerSound*> (s))
81 {
82 pitchRatio = std::pow (2.0, (midiNoteNumber - sound->midiRootNote) / 12.0)
83 * sound->sourceSampleRate / getSampleRate();
84
85 sourceSamplePosition = 0.0;
86 lgain = velocity;
87 rgain = velocity;
88
89 adsr.setSampleRate (sound->sourceSampleRate);
90 adsr.setParameters (sound->params);
91
92 adsr.noteOn();
93 }
94 else
95 {
96 jassertfalse; // this object can only play SamplerSounds!
97 }
98}
99
100void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff)
101{
102 if (allowTailOff)
103 {
104 adsr.noteOff();
105 }
106 else
107 {
109 adsr.reset();
110 }
111}
112
113void SamplerVoice::pitchWheelMoved (int /*newValue*/) {}
114void SamplerVoice::controllerMoved (int /*controllerNumber*/, int /*newValue*/) {}
115
116//==============================================================================
117void SamplerVoice::renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
118{
119 if (auto* playingSound = static_cast<SamplerSound*> (getCurrentlyPlayingSound().get()))
120 {
121 auto& data = *playingSound->data;
122 const float* const inL = data.getReadPointer (0);
123 const float* const inR = data.getNumChannels() > 1 ? data.getReadPointer (1) : nullptr;
124
125 float* outL = outputBuffer.getWritePointer (0, startSample);
126 float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getWritePointer (1, startSample) : nullptr;
127
128 while (--numSamples >= 0)
129 {
130 auto pos = (int) sourceSamplePosition;
131 auto alpha = (float) (sourceSamplePosition - pos);
132 auto invAlpha = 1.0f - alpha;
133
134 // just using a very simple linear interpolation here..
135 float l = (inL[pos] * invAlpha + inL[pos + 1] * alpha);
136 float r = (inR != nullptr) ? (inR[pos] * invAlpha + inR[pos + 1] * alpha)
137 : l;
138
139 auto envelopeValue = adsr.getNextSample();
140
141 l *= lgain * envelopeValue;
142 r *= rgain * envelopeValue;
143
144 if (outR != nullptr)
145 {
146 *outL++ += l;
147 *outR++ += r;
148 }
149 else
150 {
151 *outL++ += (l + r) * 0.5f;
152 }
153
154 sourceSamplePosition += pitchRatio;
155
156 if (sourceSamplePosition > playingSound->length)
157 {
158 stopNote (0.0f, false);
159 break;
160 }
161 }
162 }
163}
164
165} // namespace juce
void setSampleRate(double newSampleRate) noexcept
Sets the sample rate that will be used for the envelope.
Definition juce_ADSR.h:103
void noteOff() noexcept
Starts the release phase of the envelope.
Definition juce_ADSR.h:137
void reset() noexcept
Resets the envelope to an idle state.
Definition juce_ADSR.h:111
float getNextSample() noexcept
Returns the next sample value for an ADSR object.
Definition juce_ADSR.h:158
void setParameters(const Parameters &newParameters)
Sets the parameters that will be used by an ADSR object.
Definition juce_ADSR.h:80
void noteOn() noexcept
Starts the attack phase of the envelope.
Definition juce_ADSR.h:118
A multi-channel buffer containing floating point audio samples.
Reads samples from an audio file stream.
bool read(float *const *destChannels, int numDestChannels, int64 startSampleInSource, int numSamplesToRead)
Reads samples from the stream.
int64 lengthInSamples
The total number of samples in the audio stream.
unsigned int numChannels
The total number of channels in the audio stream.
An arbitrarily large integer class.
A subclass of SynthesiserSound that represents a sampled audio clip.
bool appliesToChannel(int midiChannel) override
Returns true if the sound should be triggered by midi events on a given channel.
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.
bool appliesToNote(int midiNoteNumber) override
Returns true if this sound should be played when a given midi note is pressed.
~SamplerSound() override
Destructor.
~SamplerVoice() override
Destructor.
void startNote(int midiNoteNumber, float velocity, SynthesiserSound *, int pitchWheel) override
Called to start a new note.
void controllerMoved(int controllerNumber, int newValue) override
Called to let the voice know that a midi controller has been moved.
bool canPlaySound(SynthesiserSound *) override
Must return true if this voice object is capable of playing the given sound.
void renderNextBlock(AudioBuffer< float > &, int startSample, int numSamples) override
Renders the next block of data for this voice.
void pitchWheelMoved(int newValue) override
Called to let the voice know that the pitch wheel has been moved.
SamplerVoice()
Creates a SamplerVoice.
void stopNote(float velocity, bool allowTailOff) override
Called to stop a note.
The JUCE String class!
Definition juce_String.h:53
Describes one of the sounds that a Synthesiser can play.
double getSampleRate() const noexcept
Returns the current target sample rate at which rendering is being done.
void clearCurrentNote()
Resets the state of this voice after a sound has finished playing.
SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept
Returns the sound that this voice is currently playing.
#define jassertfalse
This will always cause an assertion failure.
typedef int
typedef float
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
T pow(T... args)