File: sampler_kernel.h

package info (click to toggle)
lsp-plugins 1.2.26-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 130,004 kB
  • sloc: cpp: 642,749; xml: 78,805; makefile: 14,229; php: 1,361; sh: 185
file content (377 lines) | stat: -rw-r--r-- 25,980 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
/*
 * Copyright (C) 2025 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2025 Vladimir Sadovnikov <sadko4u@gmail.com>
 *
 * This file is part of lsp-plugins-sampler
 * Created on: 12 июл. 2021 г.
 *
 * lsp-plugins-sampler is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * lsp-plugins-sampler is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with lsp-plugins-sampler. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef PRIVATE_PLUGINS_SAMPLER_KERNEL_H_
#define PRIVATE_PLUGINS_SAMPLER_KERNEL_H_

#include <lsp-plug.in/plug-fw/plug.h>
#include <lsp-plug.in/dsp-units/ctl/Toggle.h>
#include <lsp-plug.in/dsp-units/ctl/Bypass.h>
#include <lsp-plug.in/dsp-units/ctl/Blink.h>
#include <lsp-plug.in/dsp-units/sampling/Sample.h>
#include <lsp-plug.in/dsp-units/sampling/SamplePlayer.h>
#include <lsp-plug.in/dsp-units/util/Randomizer.h>
#include <lsp-plug.in/lltl/parray.h>
#include <lsp-plug.in/ipc/ITask.h>
#include <private/meta/sampler.h>

namespace lsp
{
    namespace plugins
    {
        /**
         * Sampler implementation for single-channel audio sampler
         */
        class sampler_kernel
        {
            protected:
                struct afile_t;

                class AFLoader: public ipc::ITask
                {
                    private:
                        sampler_kernel         *pCore;
                        afile_t                *pFile;

                    public:
                        explicit AFLoader(sampler_kernel *base, afile_t *descr);
                        virtual ~AFLoader();

                    public:
                        virtual status_t        run();
                        void                    dump(dspu::IStateDumper *v) const;
                };

                class AFRenderer: public ipc::ITask
                {
                    private:
                        sampler_kernel         *pCore;
                        afile_t                *pFile;

                    public:
                        explicit AFRenderer(sampler_kernel *base, afile_t *descr);
                        virtual ~AFRenderer();

                    public:
                        virtual status_t        run();
                        void                    dump(dspu::IStateDumper *v) const;
                };

                class GCTask: public ipc::ITask
                {
                    private:
                        sampler_kernel         *pCore;

                    public:
                        explicit GCTask(sampler_kernel *base);
                        virtual ~GCTask();

                    public:
                        virtual status_t        run();
                        void                    dump(dspu::IStateDumper *v) const;
                };

            protected:
                enum crossfade_t
                {
                    XFADE_LINEAR,
                    XFADE_CONST_POWER,
                    XFADE_DFL = XFADE_CONST_POWER
                };

                enum play_mode_t
                {
                    PLAY_NOTE,
                    PLAY_INSTRUMENT,
                    PLAY_FILE
                };

                enum loop_mode_t
                {
                    LOOP_DIRECT,
                    LOOP_REVERSE,
                    LOOP_DIRECT_HALF_PP,
                    LOOP_REVERSE_HALF_PP,
                    LOOP_DIRECT_FULL_PP,
                    LOOP_REVERSE_FULL_PP,
                    LOOP_DIRECT_SMART_PP,
                    LOOP_REVERSE_SMART_PP
                };

                struct render_params_t
                {
                    ssize_t             nLength;                                        // Length before head & tail cut
                    ssize_t             nHeadCut;                                       // The amount of head cut
                    ssize_t             nTailCut;                                       // The amount of tail cut
                    ssize_t             nCutLength;                                     // Length after head & tail cut
                    ssize_t             nStretchDelta;                                  // Stretch delta
                    ssize_t             nStretchStart;                                  // Stretch start position
                    ssize_t             nStretchEnd;                                    // Stretch end position
                };

                struct afile_t
                {
                    uint32_t            nID;                                            // ID of sample
                    AFLoader           *pLoader;                                        // Audio file loader task
                    AFRenderer         *pRenderer;                                      // Audio file renderer task
                    dspu::Toggle        sListen;                                        // Listen sample preview toggle
                    dspu::Toggle        sStop;                                          // Stop listen sample preview toggle
                    dspu::Blink         sNoteOn;                                        // Note on led
                    dspu::Playback      vPlayback[4];                                   // Active playback handle
                    dspu::Playback      vListen[4];                                     // Listen playback handle
                    dspu::Sample       *pOriginal;                                      // Source sample (original, as from source file)
                    dspu::Sample       *pProcessed;                                     // Processed sample
                    float              *vThumbs[meta::sampler_metadata::TRACKS_MAX];    // List of thumbnails
                    float              *vCutThumbs[meta::sampler_metadata::TRACKS_MAX]; // List of thumbnails with cut-off

                    uint32_t            nUpdateReq;                                     // Update request
                    uint32_t            nUpdateResp;                                    // Update response
                    bool                bEnvEdit;                                       // Envelope editing
                    bool                bSync;                                          // Sync flag
                    float               fMinVelocity;                                   // Minimum velocity
                    float               fMaxVelocity;                                   // Maximum velocity
                    float               fPitch;                                         // Pitch (st)
                    bool                bStretchOn;                                     // Stretch enabled
                    float               fStretch;                                       // Stretch (sec)
                    float               fStretchStart;                                  // Stretch start (ms)
                    float               fStretchEnd;                                    // Stretch end (ms)
                    float               fStretchChunk;                                  // Stretch chunk (bar)
                    float               fStretchFade;                                   // Stretch cross-fade length
                    uint32_t            nStretchFadeType;                               // Stretch cross-fade type
                    dspu::sample_loop_t enLoopMode;                                     // Loop mode
                    float               fLoopStart;                                     // Stretch start (ms)
                    float               fLoopEnd;                                       // Stretch end (ms)
                    float               fLoopFade;                                      // Loop cross-fade length
                    uint32_t            nLoopFadeType;                                  // Loop cross-fade type
                    float               fHeadCut;                                       // Head cut (ms)
                    float               fTailCut;                                       // Tail cut (ms)
                    float               fFadeIn;                                        // Fade In (ms)
                    float               fFadeOut;                                       // Fade Out (ms)
                    bool                bPreReverse;                                    // Pre-reverse sample
                    bool                bPostReverse;                                   // Post-reverse sample
                    bool                bCompensate;                                    // Compensate time
                    float               fCompensateFade;                                // Compensate fade
                    float               fCompensateChunk;                               // Compensate chunk
                    uint32_t            nCompensateFadeType;                            // Compensate fade type
                    float               fPreDelay;                                      // Pre-delay
                    float               fMakeup;                                        // Makeup gain
                    float               fEnvelopeAttackTime;                            // Attack time
                    float               fEnvelopeHoldTime;                              // Hold time
                    float               fEnvelopeDecayTime;                             // Decay time
                    float               fEnvelopeSlopeTime;                             // Slope time
                    float               fEnvelopeReleaseTime;                           // Release time
                    float               fEnvelopeBreakLevel;                            // Break level
                    float               fEnvelopeSustainLevel;                          // Sustain level
                    float               fEnvelopeAttackCurve;                           // Attack curvature
                    float               fEnvelopeDecayCurve;                            // Decay curvature
                    float               fEnvelopeSlopeCurve;                            // Slope curvature
                    float               fEnvelopeReleaseCurve;                          // Release curvature
                    uint32_t            nEnvelopeAttackType;                            // Attack curve type
                    uint32_t            nEnvelopeDecayType;                             // Decay curve type
                    uint32_t            nEnvelopeSlopeType;                             // Slope curve type
                    uint32_t            nEnvelopeReleaseType;                           // Release curve type
                    float               fGains[meta::sampler_metadata::TRACKS_MAX];     // List of gain values
                    float               fLength;                                        // Length of source sample in milliseconds
                    float               fActualLength;                                  // Length of processed sample in milliseconds
                    status_t            nStatus;                                        // Loading status
                    bool                bOn;                                            // On flag
                    bool                bEnvelopeOn;                                    // Envelope is enabled
                    bool                bEnvelopeHoldOn;                                // Enable Hold point
                    bool                bEnvelopeBreakOn;                               // Enable Break point

                    plug::IPort        *pFile;                                          // Audio file port
                    plug::IPort        *pPitch;                                         // Pitch

                    plug::IPort        *pStretchOn;                                     // Stretch enabled
                    plug::IPort        *pStretch;                                       // Stretch amount
                    plug::IPort        *pStretchStart;                                  // Start of the stretch region
                    plug::IPort        *pStretchEnd;                                    // End of the stretch region
                    plug::IPort        *pStretchChunk;                                  // Stretch chunk
                    plug::IPort        *pStretchFade;                                   // Stretch cross-fade length
                    plug::IPort        *pStretchFadeType;                               // Stretch cross-fade type

                    plug::IPort        *pLoopOn;                                        // Loop enabled
                    plug::IPort        *pLoopMode;                                      // Loop mode
                    plug::IPort        *pLoopStart;                                     // Start of the loop region
                    plug::IPort        *pLoopEnd;                                       // End of the loop region
                    plug::IPort        *pLoopFadeType;                                  // Loop cross-fade type
                    plug::IPort        *pLoopFade;                                      // Loop cross-fade length

                    plug::IPort        *pHeadCut;                                       // Head cut
                    plug::IPort        *pTailCut;                                       // Tail cut
                    plug::IPort        *pFadeIn;                                        // Fade in length
                    plug::IPort        *pFadeOut;                                       // Fade out length
                    plug::IPort        *pMakeup;                                        // Makup gain

                    plug::IPort        *pEnvelopeOn;                                    // Enable envelope
                    plug::IPort        *pEnvelopeHoldOn;                                // Enable Hold point
                    plug::IPort        *pEnvelopeBreakOn;                               // Enable Break point
                    plug::IPort        *pEnvelopeAttackTime;                            // Attack time
                    plug::IPort        *pEnvelopeHoldTime;                              // Hold time
                    plug::IPort        *pEnvelopeDecayTime;                             // Decay time
                    plug::IPort        *pEnvelopeSlopeTime;                             // Slope time
                    plug::IPort        *pEnvelopeReleaseTime;                           // Release time
                    plug::IPort        *pEnvelopeBreakLevel;                            // Break level
                    plug::IPort        *pEnvelopeSustainLevel;                          // Sustain level
                    plug::IPort        *pEnvelopeAttackCurve;                           // Attack curvature
                    plug::IPort        *pEnvelopeDecayCurve;                            // Decay curvature
                    plug::IPort        *pEnvelopeSlopeCurve;                            // Slope curvature
                    plug::IPort        *pEnvelopeReleaseCurve;                          // Release curvature
                    plug::IPort        *pEnvelopeAttackType;                            // Attack curve type
                    plug::IPort        *pEnvelopeDecayType;                             // Decay curve type
                    plug::IPort        *pEnvelopeSlopeType;                             // Slope curve type
                    plug::IPort        *pEnvelopeReleaseType;                           // Release curve type

                    plug::IPort        *pVelocity;                                      // Velocity range top
                    plug::IPort        *pPreDelay;                                      // Pre-delay
                    plug::IPort        *pOn;                                            // Sample on outputflag
                    plug::IPort        *pListen;                                        // Listen sample preview
                    plug::IPort        *pStop;                                          // Stop listen sample preview
                    plug::IPort        *pPreReverse;                                    // Pre-reverse sample
                    plug::IPort        *pPostReverse;                                   // Post-reverse sample
                    plug::IPort        *pCompensate;                                    // Compensate
                    plug::IPort        *pCompensateFade;                                // Compensate fade
                    plug::IPort        *pCompensateChunk;                               // Compensate chunk
                    plug::IPort        *pCompensateFadeType;                            // Compensate fade type
                    plug::IPort        *pGains[meta::sampler_metadata::TRACKS_MAX];     // List of gain ports
                    plug::IPort        *pActive;                                        // Sample activity flag
                    plug::IPort        *pPlayPosition;                                  // Output current playback position
                    plug::IPort        *pNoteOn;                                        // Note on flag
                    plug::IPort        *pLength;                                        // Length of the file
                    plug::IPort        *pActualLength;                                  // Actual length of the file
                    plug::IPort        *pStatus;                                        // Status of the file
                    plug::IPort        *pMesh;                                          // Dump of the file data
                };

            protected:
                ipc::IExecutor     *pExecutor;                                          // Executor service
                dspu::Sample       *pGCList;                                            // Garbage collection list
                afile_t            *vFiles;                                             // List of audio files
                afile_t           **vActive;                                            // List of active audio files
                dspu::SamplePlayer  vChannels[meta::sampler_metadata::TRACKS_MAX];      // List of channels
                dspu::Bypass        vBypass[meta::sampler_metadata::TRACKS_MAX];        // List of bypasses
                dspu::Playback      vListen[4];                                         // Listen playback handle for instrument
                dspu::Blink         sActivity;                                          // Note on led for instrument
                dspu::Toggle        sListen;                                            // Listen sample preview toggle
                dspu::Toggle        sStop;                                              // Stop listen sample preview toggle
                dspu::Randomizer    sRandom;                                            // Randomizer
                GCTask              sGCTask;                                            // Garbage collection task

                size_t              nFiles;                                             // Number of files
                size_t              nActive;                                            // Number of active files
                size_t              nChannels;                                          // Number of audio channels (mono/stereo)
                float              *vBuffer;                                            // Buffer
                bool                bBypass;                                            // Bypass flag
                bool                bReorder;                                           // Reorder flag
                bool                bHandleVelocity;                                    // Velocity handling flag
                bool                bEnvelopeEdit;                                      // Envelope edit
                float               fFadeout;                                           // Fadeout in milliseconds
                float               fDynamics;                                          // Dynamics
                float               fDrift;                                             // Time drifting
                size_t              nSampleRate;                                        // Sample rate

                plug::IPort        *pDynamics;                                          // Dynamics port
                plug::IPort        *pHandleVelocity;                                    // Velocity handling
                plug::IPort        *pDrift;                                             // Time drifting port
                plug::IPort        *pSampleSel;                                         // Sample selector
                plug::IPort        *pActivity;                                          // Activity port
                plug::IPort        *pListen;                                            // Listen sample preview
                plug::IPort        *pStop;                                              // Stop listen sample preview
                uint8_t            *pData;                                              // Pointer to aligned data

            protected:
                void        destroy_state();
                status_t    load_file(afile_t *file);
                status_t    render_sample(afile_t *af);
                void        play_sample(afile_t *af, float gain, size_t delay, play_mode_t mode, bool listen);
                void        cancel_sample(afile_t *af, size_t delay);
                void        start_listen_file(afile_t *af, float gain);
                void        stop_listen_file(afile_t *af, bool force);
                void        start_listen_instrument(float velocity, float gain);
                void        stop_listen_instrument(bool force);

                void        process_file_load_requests();
                void        process_file_render_requests();
                void        process_gc_tasks();
                void        reorder_samples();
                void        process_listen_events();
                void        play_samples(float **listen, float **outs, const float **ins, size_t samples);
                void        output_parameters(size_t samples);
                afile_t    *select_active_sample(float velocity);

                template <class T>
                static void commit_value(uint32_t & counter, T & field, plug::IPort *port);
                static void commit_value(uint32_t & counter, bool & field, plug::IPort *port);

            protected:
                static void                 unload_afile(afile_t *file);
                static void                 destroy_afile(afile_t *af);
                static void                 destroy_samples(dspu::Sample *gc_list);
                static void                 destroy_sample(dspu::Sample * &sample);
                static ssize_t              compute_loop_point(const dspu::Sample *s, size_t position);
                static dspu::sample_loop_t  decode_loop_mode(plug::IPort *on, plug::IPort *mode);
                float                       compute_play_position(const afile_t *f);
                void                        dump_afile(dspu::IStateDumper *v, const afile_t *f) const;
                void                        perform_gc();

            public:
                explicit sampler_kernel();
                sampler_kernel(const sampler_kernel &) = delete;
                sampler_kernel(sampler_kernel &&) = delete;
                virtual ~sampler_kernel();

                sampler_kernel & operator = (const sampler_kernel &) = delete;
                sampler_kernel & operator = (sampler_kernel &&) = delete;

            public:
                void        trigger_on(size_t timestamp, uint8_t midi_velocity);
                void        trigger_off(size_t timestamp, bool handle);
                void        trigger_cancel(size_t timestamp);

            public:
                void        set_fadeout(float length);
                void        set_envelope_edit(bool edit);

            public:
                bool        init(ipc::IExecutor *executor, size_t files, size_t channels);
                void        bind(plug::IPort **ports, size_t & port_id, bool dynamics);
                void        bind_activity(plug::IPort **ports, size_t & port_id);
                void        destroy();

                void        update_settings();
                void        update_sample_rate(long sr);
                void        sync_samples_with_ui();

                /** Process the sampler kernel
                 *
                 * @param lisents list of outputs for listen events
                 * @param outs list of outputs (should be not the sampe as ins)
                 * @param ins list of inputs, elements may be NULL
                 * @param samples number of samples to process
                 */
                void        process(float **listens, float **outs, const float **ins, size_t samples);

                void        dump(dspu::IStateDumper *v) const;
        };
    } /* namespace plugins */
} /* namespace lsp */

#endif /* PRIVATE_PLUGINS_SAMPLER_KERNEL_H_ */