Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
sample_low_level_reader.h
1/*
2 * Copyright © 2018-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include "arm_neon_shim.h"
21
22#include "definitions_cxx.hpp"
23#include "dsp/interpolate/interpolate.h"
24#include <array>
25#include <cstdint>
26#define REASSESSMENT_ACTION_STOP_OR_LOOP 0
27#define REASSESSMENT_ACTION_NEXT_CLUSTER 1
28
30class Voice;
31class Sample;
32class Cluster;
33class TimeStretcher;
35
36class SampleLowLevelReader {
37public:
38 SampleLowLevelReader() = default;
39 virtual ~SampleLowLevelReader() { unassignAllReasons(false); };
40 explicit SampleLowLevelReader(SampleLowLevelReader&, bool stealReasons = false);
41 SampleLowLevelReader(SampleLowLevelReader&& other) noexcept;
42 SampleLowLevelReader& operator=(const SampleLowLevelReader& other) = delete;
43 SampleLowLevelReader& operator=(SampleLowLevelReader&& other) noexcept;
44
45 void unassignAllReasons(bool wontBeUsedAgain);
46 void jumpForwardLinear(int32_t numChannels, int32_t byteDepth, uint32_t bitMask, int32_t jumpAmount,
47 int32_t phaseIncrement);
48 void jumpForwardZeroes(int32_t bufferSize, int32_t numChannels, int32_t phaseIncrement);
49 void fillInterpolationBufferRetrospectively(Sample* sample, int32_t bufferSize, int32_t startI,
50 int32_t playDirection);
51 void jumpBackSamples(Sample* sample, int32_t numToJumpBack, int32_t playDirection);
52 void setupForPlayPosMovedIntoNewCluster(SamplePlaybackGuide* guide, Sample* sample, int32_t bytePosWithinNewCluster,
53 int32_t byteDepth);
54 bool setupClusersForInitialPlay(SamplePlaybackGuide* guide, Sample* sample, int32_t byteOvershoot = 0,
55 bool justLooped = false, int32_t priorityRating = 1);
56 bool moveOnToNextCluster(SamplePlaybackGuide* guide, Sample* sample, int32_t priorityRating = 1);
57 bool changeClusterIfNecessary(SamplePlaybackGuide* guide, Sample* sample, bool loopingAtLowLevel,
58 int32_t priorityRating = 1);
59 bool considerUpcomingWindow(SamplePlaybackGuide* guide, Sample* sample, int32_t* numSamples, int32_t phaseIncrement,
60 bool loopingAtLowLevel, int32_t bufferSize, bool allowEndlessSilenceAtEnd = false,
61 int32_t priorityRating = 1);
62 void setupReassessmentLocation(SamplePlaybackGuide* guide, Sample* sample);
63 void misalignPlaybackParameters(Sample* sample);
64 void realignPlaybackParameters(Sample* sample);
65 bool reassessReassessmentLocation(SamplePlaybackGuide* guide, Sample* sample, int32_t priorityRating);
66 int32_t getPlayByteLowLevel(Sample* sample, SamplePlaybackGuide* guide,
67 bool compensateForInterpolationBuffer = false);
68
69 bool setupClustersForPlayFromByte(SamplePlaybackGuide* guide, Sample* sample, int32_t startPlaybackAtByte,
70 int32_t priorityRating);
71
72 [[nodiscard]] virtual bool shouldObeyMarkers() const { return false; }
73
74 void readSamplesNative(int32_t** __restrict__ oscBufferPos, int32_t numSamplesTotal, Sample* sample,
75 int32_t jumpAmount, int32_t numChannels, int32_t numChannelsAfterCondensing,
76 int32_t* amplitude, int32_t amplitudeIncrement, TimeStretcher* timeStretcher = nullptr,
77 bool bufferingToTimeStretcher = false);
78
79 void readSamplesResampled(int32_t** __restrict__ oscBufferPos, int32_t numSamples, Sample* sample,
80 int32_t jumpAmount, int32_t numChannels, int32_t numChannelsAfterCondensing,
81 int32_t phaseIncrement, int32_t* amplitude, int32_t amplitudeIncrement,
82 int32_t bufferSize, bool writingCache, char** __restrict__ cacheWritePos,
83 bool* doneAnySamplesYet, TimeStretcher* timeStretcher, bool bufferingToTimeStretcher,
84 int32_t whichKernel);
85
86 bool readSamplesForTimeStretching(int32_t* oscBufferPos, SamplePlaybackGuide* guide, Sample* sample,
87 int32_t numSamples, int32_t numChannels, int32_t numChannelsAfterCondensing,
88 int32_t phaseIncrement, int32_t amplitude, int32_t amplitudeIncrement,
89 bool loopingAtLowLevel, int32_t jumpAmount, int32_t bufferSize,
90 TimeStretcher* timeStretcher, bool bufferingToTimeStretcher,
91 int32_t whichPlayHead, int32_t whichKernel, int32_t priorityRating);
92 void steal_clusters(SampleLowLevelReader& other, bool stealReasons);
93
94 void bufferIndividualSampleForInterpolation(int32_t numChannels, int32_t byteDepth, char* playPosNow);
95 void bufferZeroForInterpolation(int32_t numChannels);
96
97 uint32_t oscPos{};
98 char* currentPlayPos{};
99 char* reassessmentLocation{};
100 char* clusterStartLocation{}; // You're allowed to read from this location, but not move any further "back" past it
101 uint8_t reassessmentAction{};
102 int8_t interpolationBufferSizeLastTime{}; // 0 if was previously switched off
103
104 deluge::dsp::Interpolator interpolator_{};
105
106 std::array<Cluster*, kNumClustersLoadedAhead> clusters = {nullptr, nullptr};
107
108private:
109 bool assignClusters(SamplePlaybackGuide* guide, Sample* sample, int32_t clusterIndex, int32_t priorityRating);
110 bool fillInterpolationBufferForward(SamplePlaybackGuide* guide, Sample* sample, int32_t interpolationBufferSize,
111 bool loopingAtLowLevel, int32_t numSpacesToFill, int32_t priorityRating);
112};
Definition cluster.h:34
Definition sample_playback_guide.h:28
Definition sample.h:50
Definition time_stretcher.h:37
Definition voice_sample_playback_guide.h:28
Definition voice.h:35
Definition interpolate.h:10