Vital
Loading...
Searching...
No Matches
sample_source.h
Go to the documentation of this file.
1#pragma once
2
9#include "processor.h"
10#include "json/json.h"
11#include "utils.h"
12
13using json = nlohmann::json;
14
15namespace vital {
25 class Sample {
26 public:
28 static constexpr int kDefaultSampleLength = 44100;
30 static constexpr int kUpsampleTimes = 1;
32 static constexpr int kBufferSamples = 4;
34 static constexpr int kMinSize = 4;
35
41 struct SampleData {
48 SampleData(int l, int sr, bool s) : length(l), sample_rate(sr), stereo(s) { }
49
50 int length;
52 bool stereo;
53
55 std::vector<std::unique_ptr<mono_float[]>> left_buffers;
57 std::vector<std::unique_ptr<mono_float[]>> left_loop_buffers;
59 std::vector<std::unique_ptr<mono_float[]>> right_buffers;
61 std::vector<std::unique_ptr<mono_float[]>> right_loop_buffers;
62
63 JUCE_LEAK_DETECTOR(SampleData)
64 };
65
69 Sample();
70
77 void loadSample(const mono_float* buffer, int size, int sample_rate);
78
86 void loadSample(const mono_float* left_buffer, const mono_float* right_buffer, int size, int sample_rate);
87
89 void setName(const std::string& name) { name_ = name; }
91 std::string getName() const { return name_; }
92
94 void setLastBrowsedFile(const std::string& path) { last_browsed_file_ = path; }
96 std::string getLastBrowsedFile() const { return last_browsed_file_; }
97
100
103
106
111 force_inline int activeLength() const { return active_audio_data_.load()->length * (1 << kUpsampleTimes); }
112
114 force_inline int activeSampleRate() const { return active_audio_data_.load()->sample_rate; }
115
122
126 void init();
127
134 int octaves = utils::ilog2(std::max<int>(delta, 1));
135 return std::min(octaves, (int)active_audio_data_.load()->left_buffers.size() - 1);
136 }
137
144 VITAL_ASSERT(index >= 0 && index < active_audio_data_.load()->left_buffers.size());
145
146 return active_audio_data_.load()->left_buffers[index].get();
147 }
148
153 VITAL_ASSERT(index >= 0 && index < active_audio_data_.load()->left_loop_buffers.size());
154
155 return active_audio_data_.load()->left_loop_buffers[index].get();
156 }
157
163 if (active_audio_data_.load()->stereo) {
164 VITAL_ASSERT(index >= 0 && index < active_audio_data_.load()->right_buffers.size());
165 return active_audio_data_.load()->right_buffers[index].get();
166 }
167 return getActiveLeftBuffer(index);
168 }
169
175 if (active_audio_data_.load()->stereo) {
176 VITAL_ASSERT(index >= 0 && index < active_audio_data_.load()->right_loop_buffers.size());
177 return active_audio_data_.load()->right_loop_buffers[index].get();
178 }
179 return getActiveLeftLoopBuffer(index);
180 }
181
186
192
197 void jsonToState(json data);
198
199 protected:
200 std::string name_;
201 std::string last_browsed_file_;
203 std::atomic<SampleData*> active_audio_data_;
204 std::unique_ptr<SampleData> data_;
205
206 JUCE_LEAK_DETECTOR(Sample)
207 };
208
214 class SampleSource : public Processor {
215 public:
217 static constexpr mono_float kMaxTranspose = 96.0f;
219 static constexpr mono_float kMinTranspose = -96.0f;
221 static constexpr mono_float kMaxAmplitude = 1.41421356237f;
222
224 static constexpr int kNumDownsampleTaps = 55;
226 static constexpr int kNumUpsampleTaps = 52;
227
232 enum {
246 };
247
252 enum {
256 };
257
261 SampleSource();
262
267 virtual void process(int num_samples) override;
268
273 virtual Processor* clone() const override { return new SampleSource(*this); }
274
279 Sample* getSample() { return sample_.get(); }
280
285 force_inline Output* getPhaseOutput() const { return phase_output_.get(); }
286
287 private:
295 poly_float snapTranspose(poly_float input_midi, poly_float transpose, int quantize);
296
297 poly_float pan_amplitude_;
298 int transpose_quantize_;
299 poly_float last_quantized_transpose_;
300
301 poly_float sample_index_;
302 poly_float sample_fraction_;
303 poly_float phase_inc_;
304
305 poly_mask bounce_mask_;
306
307 std::shared_ptr<cr::Output> phase_output_;
308 utils::RandomGenerator random_generator_;
309
310 std::shared_ptr<Sample> sample_;
311
312 JUCE_LEAK_DETECTOR(SampleSource)
313 };
314} // namespace vital
315
Base class for all signal-processing units in Vital.
Definition processor.h:212
Holds and manages a single sampled waveform, including stereo or mono data and multiple band-limited ...
Definition sample_source.h:25
force_inline void markUnused()
Marks this sample as "not in use," clearing the active_audio_data_ pointer.
Definition sample_source.h:185
force_inline const mono_float * getActiveLeftLoopBuffer(int index)
Retrieves a pointer to the active left loop buffer at a specific band-limited index.
Definition sample_source.h:152
std::string getName() const
Returns the user-facing name of the sample.
Definition sample_source.h:91
static constexpr int kMinSize
Minimum sample size for further downsampling.
Definition sample_source.h:34
force_inline int sampleRate() const
Returns the sample rate of the originally loaded data.
Definition sample_source.h:105
force_inline int activeLength() const
Returns the active (currently used) sample length in frames, taking into account upsample factor and ...
Definition sample_source.h:111
void setLastBrowsedFile(const std::string &path)
Sets the last browsed file path (if applicable).
Definition sample_source.h:94
force_inline int activeSampleRate() const
Returns the sample rate of the currently active sample data.
Definition sample_source.h:114
force_inline const mono_float * buffer() const
Returns a pointer to the (current) left channel buffer at the base upsample level.
Definition sample_source.h:121
SampleData * current_data_
Pointer to the currently loaded data.
Definition sample_source.h:202
Sample()
Default constructor. Initializes the sample with default noise data.
Definition sample_source.cpp:291
std::string last_browsed_file_
The last browsed file path for this sample (if any).
Definition sample_source.h:201
force_inline const mono_float * getActiveRightBuffer(int index)
Retrieves a pointer to the active right channel buffer at a band-limited index. If the sample is mono...
Definition sample_source.h:162
int getActiveIndex(mono_float delta)
Determines which band-limited buffer index should be used for a given pitch delta.
Definition sample_source.h:133
static constexpr int kDefaultSampleLength
Default length for a newly created (noise) sample if none is provided.
Definition sample_source.h:28
force_inline int upsampleLength()
Returns the length of the upsampled data (1 << kUpsampleTimes).
Definition sample_source.h:102
std::string getLastBrowsedFile() const
Returns the last browsed file path.
Definition sample_source.h:96
force_inline void markUsed()
Marks this sample as "in use" by updating the active_audio_data_ pointer.
Definition sample_source.h:183
static constexpr int kBufferSamples
Extra buffer samples at start and end to avoid interpolation issues.
Definition sample_source.h:32
static constexpr int kUpsampleTimes
Upsampling factor exponent (i.e., 1 << kUpsampleTimes).
Definition sample_source.h:30
void loadSample(const mono_float *buffer, int size, int sample_rate)
Loads a mono sample from raw float data.
Definition sample_source.cpp:295
void setName(const std::string &name)
Sets the user-facing name of the sample.
Definition sample_source.h:89
void init()
Generates default data for the sample (e.g., random noise).
Definition sample_source.cpp:321
std::unique_ptr< SampleData > data_
Owned sample data for this sample.
Definition sample_source.h:204
std::atomic< SampleData * > active_audio_data_
Atomic pointer to data in active use.
Definition sample_source.h:203
force_inline const mono_float * getActiveLeftBuffer(int index)
Retrieves a pointer to the active left channel buffer at a specific band-limited index.
Definition sample_source.h:143
std::string name_
The user-facing name of the sample.
Definition sample_source.h:200
void jsonToState(json data)
Restores the sample's state from a JSON object (including audio data).
Definition sample_source.cpp:351
force_inline int originalLength() const
Returns the length of the originally loaded sample in frames.
Definition sample_source.h:99
json stateToJson()
Exports the sample state (metadata and sample data) to a JSON object.
Definition sample_source.cpp:333
force_inline const mono_float * getActiveRightLoopBuffer(int index)
Retrieves a pointer to the active right loop buffer at a band-limited index. If the sample is mono,...
Definition sample_source.h:174
A Processor that reads from a Sample object, providing audio output with controls for looping,...
Definition sample_source.h:214
static constexpr int kNumDownsampleTaps
Number of taps used in the downsampling filter.
Definition sample_source.h:224
virtual Processor * clone() const override
Clones the SampleSource (copy constructor).
Definition sample_source.h:273
static constexpr int kNumUpsampleTaps
Number of taps used in the upsampling filter.
Definition sample_source.h:226
@ kNumInputs
Definition sample_source.h:245
@ kRandomPhase
If true, randomize phase on note start.
Definition sample_source.h:237
@ kLevel
Overall amplitude scale.
Definition sample_source.h:236
@ kKeytrack
Boolean-like input indicating if MIDI note should track pitch.
Definition sample_source.h:235
@ kTune
Fine-tune in cents.
Definition sample_source.h:240
@ kTransposeQuantize
Quantize transposition to scale or semitones.
Definition sample_source.h:239
@ kNoteCount
Tracks how many notes have been pressed.
Definition sample_source.h:244
@ kLoop
If non-zero, the sample loops.
Definition sample_source.h:241
@ kMidi
MIDI note input.
Definition sample_source.h:234
@ kPan
Stereo panning control.
Definition sample_source.h:243
@ kReset
Reset signal (trigger) to re-initialize playback.
Definition sample_source.h:233
@ kBounce
If non-zero, sample playback bounces (back/forth).
Definition sample_source.h:242
@ kTranspose
Transposition in semitones from the current note.
Definition sample_source.h:238
SampleSource()
Default constructor initializes internal state and random generator.
Definition sample_source.cpp:385
force_inline Output * getPhaseOutput() const
Retrieves an additional output that reflects the playback phase (in [0..1]) for debugging or usage.
Definition sample_source.h:285
virtual void process(int num_samples) override
Processes audio for num_samples, reading from the Sample and applying pitch, loop,...
Definition sample_source.cpp:396
static constexpr mono_float kMaxAmplitude
Maximum amplitude scale (usually sqrt(2) for stereo).
Definition sample_source.h:221
static constexpr mono_float kMinTranspose
Minimum negative transposition in semitones.
Definition sample_source.h:219
@ kNumOutputs
Definition sample_source.h:255
@ kRaw
The raw sample output (before final amplitude).
Definition sample_source.h:253
@ kLevelled
The amplitude-scaled output.
Definition sample_source.h:254
Sample * getSample()
Provides access to the owned Sample object.
Definition sample_source.h:279
static constexpr mono_float kMaxTranspose
Maximum positive transposition in semitones.
Definition sample_source.h:217
A basic random number generator for producing uniform distributions of floats.
Definition utils.h:61
#define VITAL_ASSERT(x)
Definition common.h:11
#define force_inline
Definition common.h:23
nlohmann::json json
Definition line_generator.h:7
force_inline int ilog2(int value)
Computes the floor of the base-2 logarithm of an integer (effectively the index of the highest set bi...
Definition utils.h:259
Contains classes and functions used within the Vital synthesizer framework.
float mono_float
Definition common.h:33
Declares the Processor class and related structures for handling audio processing in a polyphonic con...
Holds and manages a buffer of samples (poly_float) for a Processor's output.
Definition processor.h:35
Holds the actual audio buffers (left/right) for multiple band-limited versions (both looped and non-l...
Definition sample_source.h:41
std::vector< std::unique_ptr< mono_float[]> > right_buffers
Collection of band-limited upsample/downsample buffers for the right channel (stereo only).
Definition sample_source.h:59
std::vector< std::unique_ptr< mono_float[]> > right_loop_buffers
Collection of band-limited upsample/downsample loop buffers for the right channel (stereo only).
Definition sample_source.h:61
std::vector< std::unique_ptr< mono_float[]> > left_loop_buffers
Collection of band-limited upsample/downsample loop buffers for the left channel.
Definition sample_source.h:57
int sample_rate
Original sample rate of the data.
Definition sample_source.h:51
int length
Number of samples in the base (original) buffer.
Definition sample_source.h:50
SampleData(int l, int sr, bool s)
Constructs a SampleData with basic metadata.
Definition sample_source.h:48
bool stereo
True if the sample is stereo, false if mono.
Definition sample_source.h:52
std::vector< std::unique_ptr< mono_float[]> > left_buffers
Collection of band-limited upsample/downsample buffers for the left channel.
Definition sample_source.h:55
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...