File: sampler_kernel.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (316 lines) | stat: -rw-r--r-- 20,122 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
/*
 * Copyright (C) 2021 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2021 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
                {
                    size_t              nID;                                            // ID of sample
                    AFLoader           *pLoader;                                        // Audio file loader task
                    AFRenderer         *pRenderer;                                      // Audio file renderer task
                    dspu::Toggle        sListen;                                        // Listen 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

                    size_t              nUpdateReq;                                     // Update request
                    size_t              nUpdateResp;                                    // Update response
                    bool                bSync;                                          // Sync flag
                    float               fVelocity;                                      // 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
                    size_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
                    size_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                bReverse;                                       // Reverse sample
                    bool                bCompensate;                                    // Compensate time
                    float               fCompensateFade;                                // Compensate fade
                    float               fCompensateChunk;                               // Compensate chunk
                    size_t              nCompensateFadeType;                            // Compensate fade type
                    float               fPreDelay;                                      // Pre-delay
                    float               fMakeup;                                        // Makeup gain
                    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

                    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        *pVelocity;                                      // Velocity range top
                    plug::IPort        *pPreDelay;                                      // Pre-delay
                    plug::IPort        *pOn;                                            // Sample on outputflag
                    plug::IPort        *pListen;                                        // Listen trigger
                    plug::IPort        *pReverse;                                       // 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 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
                float               fFadeout;                                           // Fadeout in milliseconds
                float               fDynamics;                                          // Dynamics
                float               fDrift;                                             // Time drifting
                size_t              nSampleRate;                                        // Sample rate

                plug::IPort        *pDynamics;                                          // Dynamics port
                plug::IPort        *pDrift;                                             // Time drifting port
                plug::IPort        *pActivity;                                          // Activity port
                plug::IPort        *pListen;                                            // Listen trigger
                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);
                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 **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(size_t & counter, T & field, plug::IPort *port);
                static void commit_value(size_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();
                virtual ~sampler_kernel();

            public:
                void        trigger_on(size_t timestamp, float level);
                void        trigger_off(size_t timestamp, bool handle);
                void        trigger_cancel(size_t timestamp);

            public:
                void        set_fadeout(float length);

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

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

                /** Process the sampler kernel
                 *
                 * @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 **outs, const float **ins, size_t samples);

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

#endif /* PRIVATE_PLUGINS_SAMPLER_KERNEL_H_ */