Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
sample.h
1/*
2 * Copyright © 2014-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 "definitions_cxx.hpp"
21#include "model/sample/sample_cluster.h"
22#include "model/sample/sample_cluster_array.h"
23#include "storage/audio/audio_file.h"
24#include "util/container/array/ordered_resizeable_array.h"
25#include "util/container/array/ordered_resizeable_array_with_multi_word_key.h"
26#include "util/fixedpoint.h"
27#include "util/functions.h"
28#include <bit>
29#include <cstdint>
30
31#define SAMPLE_DO_LOCKS (ALPHA_OR_BETA_VERSION)
32
33enum class RawDataFormat : uint8_t {
34 NATIVE = 0,
35 FLOAT = 1,
36 UNSIGNED_8 = 2,
37 ENDIANNESS_WRONG_16 = 3,
38 ENDIANNESS_WRONG_24 = 4,
39 ENDIANNESS_WRONG_32 = 5,
40};
41
42const float MIDI_NOTE_UNSET = (-999);
43const float MIDI_NOTE_ERROR = (-1000);
44class LoadedSamplePosReason;
45class SampleCache;
47class TimeStretcher;
48class SampleHolder;
49
50class Sample final : public AudioFile {
51public:
52 Sample();
53 ~Sample() override;
54
55 void workOutBitMask();
56 Error initialize(int32_t numClusters);
57 void markAsUnloadable();
58 float determinePitch(bool doingSingleCycle, float minFreqHz, float maxFreqHz, bool doPrimeTest);
59 void workOutMIDINote(bool doingSingleCycle, float minFreqHz = 20, float maxFreqHz = 10000, bool doPrimeTest = true);
60 uint32_t getLengthInMSec();
61 SampleCache* getOrCreateCache(SampleHolder* sampleHolder, int32_t phaseIncrement, int32_t timeStretchRatio,
62 bool reversed, bool mayCreate, bool* created);
63 void deleteCache(SampleCache* cache);
64 int32_t getFirstClusterIndexWithAudioData();
65 int32_t getFirstClusterIndexWithNoAudioData();
66 Error fillPercCache(TimeStretcher* timeStretcher, int32_t startPosSamples, int32_t endPosSamples,
67 int32_t playDirection, int32_t maxNumSamplesToProcess);
68 void percCacheClusterStolen(Cluster* cluster);
69 void deletePercCache(bool beingDestructed = false);
70 uint8_t* prepareToReadPercCache(int32_t pixellatedPos, int32_t playDirection, int32_t* earliestPixellatedPos,
71 int32_t* latestPixellatedPos);
72 bool getAveragesForCrossfade(int32_t* totals, int32_t startBytePos, int32_t crossfadeLengthSamples,
73 int32_t playDirection, int32_t lengthToAverageEach);
74 void convertDataOnAnyClustersIfNecessary();
75 int32_t getMaxPeakFromZero();
76 int32_t getFoundValueCentrePoint();
77 int32_t getValueSpan();
78 void finalizeAfterLoad(uint32_t fileSize) override;
79
80 // Floating point
81 [[nodiscard]] q31_t convertToNative(float value) const { return q31_from_float(value); }
82
83 [[nodiscard]] q31_t convertToNative(int32_t value) const {
84 switch (rawDataFormat) {
85 case RawDataFormat::FLOAT:
86 return q31_from_float(std::bit_cast<float>(value));
87
88 case RawDataFormat::ENDIANNESS_WRONG_32: // Or endianness swap
89 return swapEndianness32(value);
90
91 case RawDataFormat::ENDIANNESS_WRONG_16:
92 return swapEndianness2x16(value);
93
94 case RawDataFormat::UNSIGNED_8:
95 return value ^ 0x80808080;
96
97 case RawDataFormat::ENDIANNESS_WRONG_24:
98 // handled by caller
99 [[fallthrough]];
100
101 case RawDataFormat::NATIVE:
102 // nothing to be done
103 break;
104 }
105 return value;
106 }
107
108 String tempFilePathForRecording;
109 uint8_t byteDepth{0};
110 uint32_t sampleRate{44100};
111 uint32_t audioDataStartPosBytes; // That is, the offset from the start of the WAV file
112 uint64_t audioDataLengthBytes;
113 uint32_t bitMask{0};
114 bool audioStartDetected;
115
116 uint64_t lengthInSamples;
117
118 // These two are for holding a value loaded from file
119 uint32_t fileLoopStartSamples; // And during recording, this one also stores the final value once known
120 uint32_t fileLoopEndSamples;
121
122 float midiNoteFromFile; // -1 means none
123
124 RawDataFormat rawDataFormat;
125
126 bool unloadable{false}; // Only gets set to true if user has re-inserted the card and the sample appears to have
127 // been deleted / moved / modified
128 bool unplayable{false};
129 bool partOfFolderBeingLoaded;
130 bool fileExplicitlySpecifiesSelfAsWaveTable{false};
131
132#if SAMPLE_DO_LOCKS
133 bool lock;
134#endif
135
136 float midiNote; // -999 means not worked out yet. -1000 means error working out
137
138 // int32_t valueSpan; // -2147483648 means both these are uninitialized
139 int32_t minValueFound;
140 int32_t maxValueFound;
141
143
144 uint8_t* percCacheMemory[2]{nullptr, nullptr}; // One for each play-direction: 0=forwards; 1=reversed
145 OrderedResizeableArrayWith32bitKey percCacheZones[2]; // One for each play-direction: 0=forwards; 1=reversed
146
147 Cluster** percCacheClusters[2]{nullptr, nullptr}; // One for each play-direction: 0=forwards; 1=reversed
148 int32_t numPercCacheClusters{};
149
150 int32_t beginningOffsetForPitchDetection;
151 bool beginningOffsetForPitchDetectionFound;
152
153 uint32_t waveTableCycleSize{0}; // In case this later gets used for a WaveTable
154
155 SampleClusterArray clusters;
156
157 // Stealable Implementation
158 bool mayBeStolen(void* thingNotToStealFrom = nullptr) override;
159 void steal(char const* errorCode) override;
160
161protected:
162#if ALPHA_OR_BETA_VERSION
163 void numReasonsDecreasedToZero(char const* errorCode) override;
164#endif
165
166private:
167 int32_t investigateFundamentalPitch(int32_t fundamentalIndexProvided, int32_t tableSize, int32_t* heightTable,
168 uint64_t* sumTable, float* floatIndexTable, float* getFreq,
169 int32_t numDoublings, bool doPrimeTest);
170};
Definition cluster.h:34
Definition multisample_range.h:27
Definition ordered_resizeable_array.h:72
Definition ordered_resizeable_array_with_multi_word_key.h:25
Definition sample_cache.h:25
Definition sample_cluster_array.h:25
Definition sample_holder.h:32
Definition d_string.h:46
Definition time_stretcher.h:37