Audacity 3.2.0
Sequence.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Sequence.h
6
7 Dominic Mazzoni
8
9**********************************************************************/
10
11#ifndef __AUDACITY_SEQUENCE__
12#define __AUDACITY_SEQUENCE__
13
14#include <atomic>
15#include <deque>
16#include <functional>
17
18#include "SampleFormat.h"
19#include "XMLTagHandler.h"
20
21#include "SampleCount.h"
23
24class SampleBlock;
26using SampleBlockFactoryPtr = std::shared_ptr<SampleBlockFactory>;
27
28// This is an internal data structure! For advanced use only.
29class SeqBlock {
30 public:
31 using SampleBlockPtr = std::shared_ptr<SampleBlock>;
35
37 : sb{}, start(0)
38 {}
39
41 : sb(sb_), start(start_)
42 {}
43
44 // Construct a SeqBlock with changed start, same file
46 {
47 return SeqBlock(sb, start + delta);
48 }
49};
50class BlockArray : public std::deque<SeqBlock> {};
51using BlockPtrArray = std::deque<SeqBlock*>; // non-owning pointers
52
53class WAVE_TRACK_API Sequence final : public XMLTagHandler{
54 public:
55
56 static const char *Sequence_tag;
57 static const char *WaveBlock_tag;
58
59 //
60 // Static methods
61 //
62
63 static void SetMaxDiskBlockSize(size_t bytes);
64 static size_t GetMaxDiskBlockSize();
65
67 static bool IsValidSampleFormat(const int nValue);
68
69 //
70 // Constructor / Destructor / Duplicator
71 //
72
73 Sequence(const SampleBlockFactoryPtr &pFactory, SampleFormats formats);
74
76 Sequence(const Sequence &orig, const SampleBlockFactoryPtr &pFactory);
77
78 Sequence( const Sequence& ) = delete;
79 Sequence& operator= (const Sequence&) = delete;
80
81 ~Sequence();
82
83 //
84 // Editing
85 //
86
87 sampleCount GetNumSamples() const { return mNumSamples; }
88
90 /*
91 If the requested range is not all defined, the buffer may still contain
92 valid results, with zero filling
93
94 @param start offset into sequence
95 @param len number of samples to put in buffer
96 @param mayThrow if true, propagate read error exceptions
97 @return whether [start, start + len) was within the defined range of the
98 sequence and there were no read errors
99 */
100 bool Get(samplePtr buffer, sampleFormat format,
101 sampleCount start, size_t len, bool mayThrow) const;
102
108 GetFloatSampleView(sampleCount start, size_t len, bool mayThrow) const;
109
111
114 void SetSamples(constSamplePtr buffer, sampleFormat format,
115 sampleCount start, sampleCount len,
116 sampleFormat effectiveFormat
122 );
123
124 // Return non-null, or else throw!
125 // Must pass in the correct factory for the result. If it's not the same
126 // as in this, then block contents must be copied.
127 std::unique_ptr<Sequence> Copy( const SampleBlockFactoryPtr &pFactory,
128 sampleCount s0, sampleCount s1) const;
130 void Paste(sampleCount s0, const Sequence *src);
131
132 size_t GetIdealAppendLen() const;
133
142 bool Append(
143 constSamplePtr buffer, sampleFormat format, size_t len, size_t stride,
144 sampleFormat effectiveFormat
150 );
151
157 void Flush();
158
161
162 SeqBlock::SampleBlockPtr AppendNewBlock(
163 constSamplePtr buffer, sampleFormat format, size_t len);
165
166 void AppendSharedBlock(const SeqBlock::SampleBlockPtr &pBlock);
168 void Delete(sampleCount start, sampleCount len);
169
171 void SetSilence(sampleCount s0, sampleCount len);
173 void InsertSilence(sampleCount s0, sampleCount len);
174
176 {
177 return mpFactory;
178 }
179
180 //
181 // XMLTagHandler callback methods for loading and saving
182 //
183
184 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
185 void HandleXMLEndTag(const std::string_view& tag) override;
186 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
187 void WriteXML(XMLWriter &xmlFile) const /* not override */;
188
189 bool GetErrorOpening() const { return mErrorOpening; }
190
191 //
192 // Lock all of this sequence's sample blocks, keeping them
193 // from being destroyed when closing.
194
196
197 bool CloseLock() noexcept;
198
199 //
200 // Manipulating Sample Format
201 //
202
203 SampleFormats GetSampleFormats() const;
204
206
207 bool ConvertToSampleFormat(sampleFormat format,
208 const std::function<void(size_t)> & progressReport = {});
209
210 //
211 // Retrieving summary info
212 //
213
214 std::pair<float, float> GetMinMax(
215 sampleCount start, sampleCount len, bool mayThrow) const;
216 float GetRMS(sampleCount start, sampleCount len, bool mayThrow) const;
217
218 //
219 // Getting block size and alignment information
220 //
221
222 // These return a nonnegative number of samples meant to size a memory buffer
223 size_t GetBestBlockSize(sampleCount start) const;
224 size_t GetMaxBlockSize() const;
225 size_t GetIdealBlockSize() const;
226
227 //
228 // This should only be used if you really, really know what
229 // you're doing!
230 //
231 const BlockArray &GetBlockArray() const { return mBlock; }
232
233 size_t GetAppendBufferLen() const { return mAppendBufferLen; }
234 constSamplePtr GetAppendBuffer() const { return mAppendBuffer.ptr(); }
235
236 private:
237
238 //
239 // Private static variables
240 //
241
242 static size_t sMaxDiskBlockSize;
243
244 //
245 // Private variables
246 //
247
249 std::atomic<size_t> mBlockCount{ 0 };
252
253 // Not size_t! May need to be large:
254 sampleCount mNumSamples{ 0 };
255
256 size_t mMinSamples; // min samples per block
257 size_t mMaxSamples; // max samples per block
258
259 SampleBuffer mAppendBuffer {};
260 size_t mAppendBufferLen { 0 };
261 sampleFormat mAppendEffectiveFormat{ narrowestSampleFormat };
262
263 bool mErrorOpening{ false };
264
265 //
266 // Private methods
267 //
268
270 sampleCount GetBlockStart(sampleCount position) const;
271
273
275 constSamplePtr buffer, sampleFormat format, size_t len, bool coalesce);
276
277 static void AppendBlock(SampleBlockFactory *pFactory, sampleFormat format,
278 BlockArray &blocks,
279 sampleCount &numSamples,
280 const SeqBlock &b);
281
282 // Accumulate NEW block files onto the end of a block array.
283 // Does not change this sequence. The intent is to use
284 // CommitChangesIfConsistent later.
285 static void Blockify(SampleBlockFactory &factory,
286 size_t maxSamples,
288 BlockArray &list,
289 sampleCount start,
290 constSamplePtr buffer,
291 size_t len);
292
293 bool Get(int b,
294 samplePtr buffer,
296 sampleCount start,
297 size_t len,
298 bool mayThrow) const;
299
300public:
301
302 //
303 // Public methods
304 //
305
306 int FindBlock(sampleCount pos) const;
307
308 static bool Read(samplePtr buffer, sampleFormat format,
309 const SeqBlock &b,
310 size_t blockRelativeStart, size_t len, bool mayThrow);
311
312 // This function throws if the track is messed up
313 // because of inconsistent block starts & lengths
314 void ConsistencyCheck (const wxChar *whereStr, bool mayThrow = true) const;
315
316 // This function prints information to stdout about the blocks in the
317 // tracks and indicates if there are inconsistencies.
318 static void DebugPrintf
319 (const BlockArray &block, sampleCount numSamples, wxString *dest);
320
321private:
323 (const BlockArray &block, size_t maxSamples, size_t from,
324 sampleCount numSamples, const wxChar *whereStr,
325 bool mayThrow = true);
326
327 // The next two are used in methods that give a strong guarantee.
328 // They either throw because final consistency check fails, or swap the
329 // changed contents into place.
330
331 void CommitChangesIfConsistent
332 (BlockArray &newBlock, sampleCount numSamples, const wxChar *whereStr);
333
334 void AppendBlocksIfConsistent
335 (BlockArray &additionalBlocks, bool replaceLast,
336 sampleCount numSamples, const wxChar *whereStr);
337
338};
339
340#endif // __AUDACITY_SEQUENCE__
341
An audio segment is either a whole clip or the silence between clips. Views allow shared references t...
static RegisteredToolbarFactory factory
std::shared_ptr< SampleBlockFactory > SampleBlockFactoryPtr
Definition: SampleBlock.h:31
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.
char * samplePtr
Definition: SampleFormat.h:57
const char * constSamplePtr
Definition: SampleFormat.h:58
std::deque< SeqBlock * > BlockPtrArray
Definition: Sequence.h:51
Append(Adapt< My >([](My &table) { return(WaveChannelSubViews::numFactories() > 1) ? std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveChannelView::GetFirst(track);menu.Check(id, view.GetMultiView());}) :nullptr;}))
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
abstract base class with methods to produce SampleBlock objects
Definition: SampleBlock.h:115
Abstract class allows access to contents of a block of sound samples, serialization as XML,...
Definition: SampleBlock.h:47
Two sample formats, remembering format of original source and describing stored format.
Definition: SampleFormat.h:79
Data structure containing pointer to a sample block and a start time. Element of a BlockArray.
Definition: Sequence.h:29
sampleCount start
the sample in the global wavetrack that this block starts at.
Definition: Sequence.h:34
SampleBlockPtr sb
Definition: Sequence.h:32
SeqBlock()
Definition: Sequence.h:36
std::shared_ptr< SampleBlock > SampleBlockPtr
Definition: Sequence.h:31
SeqBlock(const SampleBlockPtr &sb_, sampleCount start_)
Definition: Sequence.h:40
SeqBlock Plus(sampleCount delta) const
Definition: Sequence.h:45
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53
bool GetErrorOpening() const
Definition: Sequence.h:189
size_t GetAppendBufferLen() const
Definition: Sequence.h:233
BlockArray mBlock
Definition: Sequence.h:250
const BlockArray & GetBlockArray() const
Definition: Sequence.h:231
const SampleBlockFactoryPtr & GetFactory() const
Definition: Sequence.h:175
SampleBlockFactoryPtr mpFactory
Definition: Sequence.h:248
static void ConsistencyCheck(const BlockArray &block, size_t maxSamples, size_t from, sampleCount numSamples, const wxChar *whereStr, bool mayThrow=true)
static size_t sMaxDiskBlockSize
Definition: Sequence.h:242
static const char * Sequence_tag
Definition: Sequence.h:56
sampleCount GetNumSamples() const
Definition: Sequence.h:87
constSamplePtr GetAppendBuffer() const
Definition: Sequence.h:234
static const char * WaveBlock_tag
Definition: Sequence.h:57
size_t mMinSamples
Definition: Sequence.h:256
Sequence(const Sequence &)=delete
size_t mMaxSamples
Definition: Sequence.h:257
SampleFormats mSampleFormats
Definition: Sequence.h:251
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
virtual XMLTagHandler * HandleXMLChild(const std::string_view &tag)=0
virtual void HandleXMLEndTag(const std::string_view &WXUNUSED(tag))
Definition: XMLTagHandler.h:59
virtual bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs)=0
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:202
WAVE_TRACK_API std::pair< float, float > GetMinMax(const WaveChannel &channel, double t0, double t1, bool mayThrow=true)
WAVE_TRACK_API float GetRMS(const WaveChannel &channel, double t0, double t1, bool mayThrow=true)
WAVE_TRACK_API void CloseLock(WaveTrack &track) noexcept
Should be called upon project close. Not balanced by unlocking calls.
STL namespace.