57 mSampleFormats{ formats },
58 mMinSamples(sMaxDiskBlockSize /
SAMPLE_SIZE(mSampleFormats.Stored()) / 2),
59 mMaxSamples(mMinSamples * 2)
69 mSampleFormats{ orig.mSampleFormats },
70 mMinSamples(orig.mMinSamples),
71 mMaxSamples(orig.mMaxSamples)
92 const size_t blockCount =
mBlockCount.load(std::memory_order_relaxed);
94 for (
unsigned int i = 0; i < blockCount; i++)
107 size_t &
size,
size_t required,
113 if (
size < required) {
116 if (pSecondBuffer && pSecondBuffer->ptr())
118 if (!buffer.
ptr() || (pSecondBuffer && !pSecondBuffer->ptr())) {
132 const std::function<
void(
size_t)> & progressReport)
138 const size_t blockCount =
mBlockCount.load(std::memory_order_relaxed);
159 bool bSuccess =
false;
160 auto cleanup =
finally( [&] {
172 size_t oldSize = oldMaxSamples;
174 size_t newSize = oldMaxSamples;
177 for (
size_t i = 0; i < blockCount; i++)
180 const auto &oldBlockFile = oldSeqBlock.
sb;
181 const auto len = oldBlockFile->GetSampleCount();
185 Read(bufferOld.
ptr(), oldFormats.Stored(), oldSeqBlock, 0, len,
true);
190 bufferOld.
ptr(), oldFormats.Stored(), bufferNew.
ptr(),
format, len,
194 format < oldFormats.Effective()
208 const auto blockstart = oldSeqBlock.
start;
210 newBlockArray, blockstart, bufferNew.
ptr(), len);
222 (newBlockArray,
mNumSamples,
wxT(
"Sequence::ConvertToSampleFormat()"));
233 const size_t blockCount =
mBlockCount.load(std::memory_order_relaxed);
235 if (len == 0 || blockCount == 0) {
246 float max = -FLT_MAX;
249 unsigned int block1 =
FindBlock(start + len - 1);
255 for (
unsigned b = block0 + 1; b < block1; ++b) {
256 auto results =
mBlock[b].sb->GetMinMaxRMS(mayThrow);
258 if (results.min <
min)
260 if (results.max > max)
270 const auto &theFile = theBlock.
sb;
271 auto results = theFile->GetMinMaxRMS(mayThrow);
273 if (results.min <
min || results.max > max) {
275 auto s0 = ( start - theBlock.
start ).as_size_t();
278 theBlock.
start + theFile->GetSampleCount() - start
283 results = theFile->GetMinMaxRMS(s0, l0, mayThrow);
284 if (results.min <
min)
286 if (results.max > max)
294 const auto &theFile = theBlock.
sb;
295 auto results = theFile->GetMinMaxRMS(mayThrow);
297 if (results.min <
min || results.max > max) {
300 const auto l0 = ( start + len - theBlock.
start ).as_size_t();
303 results = theFile->GetMinMaxRMS(0, l0, mayThrow);
304 if (results.min <
min)
306 if (results.max > max)
318 const size_t blockCount =
mBlockCount.load(std::memory_order_relaxed);
320 if (len == 0 || blockCount == 0)
327 unsigned int block1 =
FindBlock(start + len - 1);
332 for (
unsigned b = block0 + 1; b < block1; b++) {
334 const auto &sb = theBlock.
sb;
335 auto results = sb->GetMinMaxRMS(mayThrow);
337 const auto fileLen = sb->GetSampleCount();
338 const auto blockRMS = results.RMS;
339 sumsq += blockRMS * blockRMS * fileLen;
348 const auto &sb = theBlock.
sb;
350 auto s0 = ( start - theBlock.
start ).as_size_t();
353 (theBlock.
start + sb->GetSampleCount() - start).as_size_t();
357 auto results = sb->GetMinMaxRMS(s0, l0, mayThrow);
358 const auto partialRMS = results.RMS;
359 sumsq += partialRMS * partialRMS * l0;
363 if (block1 > block0) {
365 const auto &sb = theBlock.
sb;
368 const auto l0 = ( start + len - theBlock.
start ).as_size_t();
371 auto results = sb->GetMinMaxRMS(0, l0, mayThrow);
372 const auto partialRMS = results.RMS;
373 sumsq += partialRMS * partialRMS * l0;
378 wxASSERT(length == len);
396 auto pUseFactory = (pFactory ==
mpFactory) ?
nullptr : pFactory.get();
398 const size_t blockCount =
mBlockCount.load(std::memory_order_relaxed);
403 wxASSERT(b0 < blockCount);
404 wxASSERT(b1 < blockCount);
405 wxUnusedVar(blockCount);
417 if (s0 != block0.
start) {
418 const auto &sb = block0.
sb;
421 (
std::min(s1, block0.
start + sb->GetSampleCount()) - s0 ).as_size_t();
434 for (
int bb = b0 + 1; bb < b1; ++bb)
436 dest->mBlock, dest->mNumSamples,
mBlock[bb]);
443 const auto &sb = block.
sb;
445 blocklen = (s1 - block.
start).as_size_t();
447 if (blocklen < (
int)sb->GetSampleCount()) {
457 dest->mBlock, dest->mNumSamples, block);
461 dest->ConsistencyCheck(
wxT(
"Sequence::Copy()"));
469 return numSamples > wxLL(9223372036854775807);
495 wxT(
"Sequence::Paste: sampleCount s %s is < 0 or > mNumSamples %s)."),
506 wxT(
"Sequence::Paste: mNumSamples %s + src->mNumSamples %s would overflow."),
517 wxT(
"Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."),
525 const size_t srcNumBlocks = src->
mBlockCount.load(std::memory_order_relaxed);
528 if (addedLen == 0 || srcNumBlocks == 0)
531 const size_t numBlocks =
mBlockCount.load(std::memory_order_relaxed);
538 if (numBlocks == 0 ||
547 for (
unsigned int i = 0; i < srcNumBlocks; i++)
551 newBlock, samples, srcBlock[i]);
554 (newBlock, samples,
wxT(
"Paste branch one"));
560 wxASSERT((b >= 0) && (b < (
int)numBlocks));
562 const auto length = pBlock->
sb->GetSampleCount();
563 const auto largerBlockLen = addedLen + length;
576 auto sAddedLen = addedLen.as_size_t();
578 auto splitPoint = ( s - block.
start ).as_size_t();
580 src->
Get(0, buffer.
ptr() + splitPoint*sampleSize,
581 format, 0, sAddedLen,
true);
582 Read(buffer.
ptr() + (splitPoint + sAddedLen) * sampleSize,
584 splitPoint, length - splitPoint,
true);
589 largerBlockLen.as_size_t(),
596 for (
unsigned int i = b + 1; i < numBlocks; i++)
597 mBlock[i].start += addedLen;
614 newBlock.insert(newBlock.end(),
mBlock.begin(),
mBlock.begin() + b);
617 auto splitLen = splitBlock.
sb->GetSampleCount();
619 auto splitPoint = ( s - splitBlock.
start ).as_size_t();
622 if (srcNumBlocks <= 4) {
625 auto sAddedLen = addedLen.as_size_t();
626 const auto sum = splitLen + sAddedLen;
629 Read(sumBuffer.
ptr(),
format, splitBlock, 0, splitPoint,
true);
630 src->
Get(0, sumBuffer.
ptr() + splitPoint * sampleSize,
633 Read(sumBuffer.
ptr() + (splitPoint + sAddedLen) * sampleSize,
format,
634 splitBlock, splitPoint,
635 splitLen - splitPoint,
true);
638 newBlock, splitBlock.
start, sumBuffer.
ptr(), sum);
647 const auto srcFirstTwoLen =
648 srcBlock[0].sb->GetSampleCount() + srcBlock[1].sb->GetSampleCount();
649 const auto leftLen = splitPoint + srcFirstTwoLen;
651 const SeqBlock &penultimate = srcBlock[srcNumBlocks - 2];
652 const auto srcLastTwoLen =
653 penultimate.
sb->GetSampleCount() +
654 srcBlock[srcNumBlocks - 1].sb->GetSampleCount();
655 const auto rightSplit = splitBlock.
sb->GetSampleCount() - splitPoint;
656 const auto rightLen = rightSplit + srcLastTwoLen;
660 Read(sampleBuffer.
ptr(),
format, splitBlock, 0, splitPoint,
true);
661 src->
Get(0, sampleBuffer.
ptr() + splitPoint*sampleSize,
662 format, 0, srcFirstTwoLen,
true);
665 newBlock, splitBlock.
start, sampleBuffer.
ptr(), leftLen);
667 for (i = 2; i < srcNumBlocks - 2; i++) {
668 const SeqBlock &block = srcBlock[i];
674 auto lastStart = penultimate.
start;
676 lastStart, srcLastTwoLen,
true);
677 Read(sampleBuffer.
ptr() + srcLastTwoLen * sampleSize,
format,
678 splitBlock, splitPoint, rightSplit,
true);
681 newBlock, s + lastStart, sampleBuffer.
ptr(), rightLen);
686 for (i = b + 1; i < numBlocks; i++)
687 newBlock.push_back(
mBlock[i].Plus(addedLen));
725 auto nBlocks = (len + idealSamples - 1) / idealSamples;
728 if (len >= idealSamples) {
729 auto silentFile =
factory.CreateSilent(
732 while (len >= idealSamples) {
733 sTrack.mBlock.push_back(
SeqBlock(silentFile, pos));
745 sTrack.mBlockCount.store(sTrack.mBlock.size(), std::memory_order_release);
746 sTrack.mNumSamples = pos;
764 mBlock.push_back(newBlock);
788 const size_t numBlocks =
mBlockCount.load(std::memory_order_relaxed);
792 auto result = (block.
start + block.
sb->GetSampleCount() - start).as_size_t();
794 decltype(result) length;
823 if (wb.
sb ==
nullptr)
830 for (
auto pair : attrs)
832 auto attr = pair.first;
833 auto value = pair.second;
840 if (!value.TryGet(start))
857 std::optional<sampleFormat> effective;
859 for (
auto pair : attrs)
861 auto attr = pair.first;
862 auto value = pair.second;
864 long long nValue = 0;
869 if (!value.TryGet(nValue))
878 if ((nValue < 1024) || (nValue > 64 * 1024 * 1024))
914 if (!value.TryGet(nValue) || (nValue < 0))
951 const size_t blockCount =
mBlock.size();
953 for (
unsigned b = 0; b < blockCount; b++)
956 if (block.
start != numSamples)
959 wxT(
"Gap detected in project file.\n")
960 wxT(
" Start (%s) for block file %lld is not one sample past end of previous block (%s).\n")
961 wxT(
" Moving start so blocks are contiguous."),
964 block.
sb->GetBlockID(),
966 block.
start = numSamples;
969 numSamples += block.
sb->GetSampleCount();
977 wxT(
"Gap detected in project file. Correcting sequence sample count from %s to %s."),
1002 xmlFile.StartTag(Sequence_tag);
1006 static_cast<size_t>( mSampleFormats.Stored() ) );
1009 static_cast<size_t>( mSampleFormats.Effective() ));
1012 const size_t blockCount = mBlockCount.load(std::memory_order_relaxed);
1014 for (b = 0; b < blockCount; b++) {
1018 if (bb.
sb->GetSampleCount() > mMaxSamples)
1027 XO(
"Sequence has block file exceeding maximum %s samples per block.\nTruncating to this maximum length.")
1032 .
Caption(
XO(
"Warning - Truncating Overlong Block File"))
1033 .IconStyle(Icon::Warning)
1034 .ButtonStyle(Button::Ok));
1035 wxLogWarning(sMsg.Translation());
1039 xmlFile.StartTag(WaveBlock_tag);
1042 bb.
sb->SaveXML(xmlFile);
1044 xmlFile.EndTag(WaveBlock_tag);
1047 xmlFile.EndTag(Sequence_tag);
1057 const size_t numBlocks =
mBlockCount.load(std::memory_order_relaxed);
1059 size_t lo = 0, hi = numBlocks, guess;
1066 const double frac = (pos - loSamples).as_double() /
1067 (hiSamples - loSamples).as_double();
1068 guess =
std::min(hi - 1, lo +
size_t(frac * (hi - lo)));
1071 wxASSERT(block.
sb->GetSampleCount() > 0);
1072 wxASSERT(lo <= guess && guess < hi && lo < hi);
1074 if (pos < block.
start) {
1075 wxASSERT(lo != guess);
1077 hiSamples = block.
start;
1081 if (pos < nextStart)
1084 wxASSERT(guess < hi - 1);
1086 loSamples = nextStart;
1091 const int rval = guess;
1092 wxASSERT(rval >= 0 && rval < numBlocks &&
1093 pos >=
mBlock[rval].start &&
1094 pos <
mBlock[rval].start +
mBlock[rval].sb->GetSampleCount());
1101 const SeqBlock &b,
size_t blockRelativeStart,
size_t len,
1104 const auto &sb = b.
sb;
1106 wxASSERT(blockRelativeStart + len <= sb->GetSampleCount());
1109 auto result = sb->GetSamples(buffer,
format, blockRelativeStart, len, mayThrow);
1113 wxLogWarning(
wxT(
"Expected to read %ld samples, got %ld samples."),
1122 sampleCount start,
size_t length,
bool mayThrow)
const
1126 std::vector<BlockSampleView> blockViews;
1129 const auto sequenceOffset = (start -
GetBlockStart(start)).as_size_t();
1130 auto cursor = start;
1131 while (cursor < start + length)
1135 blockViews.push_back(block.
sb->GetFloatSampleView(mayThrow));
1136 cursor = block.
start + block.
sb->GetSampleCount();
1138 return { std::move(blockViews), sequenceOffset, length };
1142 sampleCount start,
size_t len,
bool mayThrow)
const
1145 bool outOfBounds =
false;
1153 buffer += fillLen * sampleSize;
1167 const auto excess = (start + len -
mNumSamples).as_size_t();
1176 return Get(b, buffer,
format, start, len, mayThrow) &&
1181 sampleCount start,
size_t len,
bool mayThrow)
const
1187 const auto bstart = (start - block.
start).as_size_t();
1189 const auto blen =
std::min(len, block.
sb->GetSampleCount() - bstart);
1191 if (!
Read(buffer,
format, block, bstart, blen, mayThrow) )
1221 if (buffer &&
format != dstFormat) {
1222 temp.
Allocate(tempSize, dstFormat);
1236 newBlock.push_back(
mBlock[b] );
1239 const auto bstart = ( start - block.
start ).as_size_t();
1240 const auto fileLength = block.
sb->GetSampleCount();
1246 wxASSERT(blen == 0 || bstart + blen <= fileLength);
1262 auto useBuffer = buffer;
1263 if (buffer &&
format != dstFormat)
1268 (dstFormat < effectiveFormat
1270 useBuffer = temp.
ptr();
1277 if ( bstart > 0 || blen < fileLength ) {
1279 Read(scratch.
ptr(), dstFormat, block, 0, fileLength,
true);
1283 memcpy(scratch.
ptr() +
1284 bstart * sampleSize, useBuffer, blen * sampleSize);
1297 block.
sb =
factory.Create(useBuffer, fileLength, dstFormat);
1299 block.
sb =
factory.CreateSilent(fileLength, dstFormat);
1322 const size_t numBlocks =
mBlockCount.load(std::memory_order_relaxed);
1329 const auto lastBlockLen =
mBlock.back().sb->GetSampleCount();
1330 if (lastBlockLen >= max)
1333 return max - lastBlockLen;
1350 auto len = pBlock->GetSampleCount();
1361 newNumSamples,
wxT(
"Append"));
1366#ifdef VERY_SLOW_CHECKING
1381 bool result =
false;
1445 int numBlocks =
mBlock.size();
1447 decltype(pLastBlock->
sb->GetSampleCount()) length;
1451 bool replaceLast =
false;
1457 const SeqBlock &lastBlock = *pLastBlock;
1461 Read(buffer2.
ptr(), dstFormat, lastBlock, 0, length,
true);
1469 const auto newLastBlockLen = length + addLen;
1476 newBlock.push_back( newLastBlock );
1479 newNumSamples += addLen;
1487 const auto addedLen =
std::min(idealSamples, len);
1489 if (
format == dstFormat) {
1490 pBlock =
factory.Create(buffer, addedLen, dstFormat);
1493 wxASSERT( coalesce || !result );
1499 pBlock =
factory.Create(buffer2.
ptr(), addedLen, dstFormat);
1502 newBlock.push_back(
SeqBlock(pBlock, newNumSamples));
1505 newNumSamples += addedLen;
1510 newNumSamples,
wxT(
"Append"));
1515#ifdef VERY_SLOW_CHECKING
1531 auto cleanup =
finally( [&] {
1559 for (
decltype(num) i = 0; i < num; i++) {
1562 const auto offset = i * len / num;
1563 b.
start = start + offset;
1564 int newLen = ((i + 1) * len / num) - offset;
1565 auto bufStart = buffer + (offset *
SAMPLE_SIZE(mSampleFormat));
1567 b.
sb =
factory.Create(bufStart, newLen, mSampleFormat);
1579 if (len < 0 || start < 0 || start + len >
mNumSamples)
1584 const unsigned int numBlocks =
mBlock.size();
1586 const unsigned int b0 =
FindBlock(start);
1587 unsigned int b1 =
FindBlock(start + len - 1);
1593 decltype(pBlock->
sb->GetSampleCount()) length;
1607 auto pos = ( start - b.
start ).as_size_t();
1610 wxASSERT(len < length);
1624 ( pos + len ).as_size_t(), newLen - pos,
true);
1633 for (
unsigned int j = b0 + 1; j < numBlocks; j++)
1649 newBlock.insert(newBlock.end(),
mBlock.begin(),
mBlock.begin() + b0);
1659 auto preBufferLen = ( start - preBlock.
start ).as_size_t();
1665 Read(scratch.
ptr(),
format, preBlock, 0, preBufferLen,
true);
1672 const auto prepreLen = prepreBlock.
sb->GetSampleCount();
1673 const auto sum = prepreLen + preBufferLen;
1680 Read(scratch.
ptr(),
format, prepreBlock, 0, prepreLen,
true);
1682 preBlock, 0, preBufferLen,
true);
1684 newBlock.pop_back();
1686 newBlock, prepreBlock.
start, scratch.
ptr(), sum);
1701 const auto postBufferLen = (
1702 (postBlock.
start + postBlock.
sb->GetSampleCount()) - (start + len)
1704 if (postBufferLen) {
1705 if (postBufferLen >=
mMinSamples || b1 == numBlocks - 1) {
1710 auto pos = (start + len - postBlock.
start).as_size_t();
1711 Read(scratch.
ptr(),
format, postBlock, pos, postBufferLen,
true);
1715 newBlock.push_back(
SeqBlock(file, start));
1718 const auto postpostLen = postpostBlock.
sb->GetSampleCount();
1719 const auto sum = postpostLen + postBufferLen;
1725 auto pos = (start + len - postBlock.
start).as_size_t();
1726 Read(scratch.
ptr(),
format, postBlock, pos, postBufferLen,
true);
1728 postpostBlock, 0, postpostLen,
true);
1731 newBlock, start, scratch.
ptr(), sum);
1741 for (i = b1 + 1; i < numBlocks; i++)
1742 newBlock.push_back(
mBlock[i].Plus(-len));
1754 (
const BlockArray &mBlock,
size_t maxSamples,
size_t from,
1756 bool WXUNUSED(mayThrow))
1760 std::optional<InconsistencyException> ex;
1762 unsigned int numBlocks =
mBlock.size();
1766 if ( from == 0 && pos != 0 )
1769 for (i = from; !ex && i < numBlocks; i++) {
1771 if (pos != seqBlock.
start)
1774 if ( seqBlock.
sb ) {
1775 const auto length = seqBlock.
sb->GetSampleCount();
1776 if (length > maxSamples)
1788 wxLogError(
wxT(
"*** Consistency check failed at %d after %s. ***"),
1789 ex->GetLine(), whereStr);
1792 wxLogError(
wxT(
"%s"),
str);
1793 wxLogError(
wxT(
"*** Please report this error to https://forum.audacityteam.org/. ***\n\n")
1794 wxT(
"Recommended course of action:\n")
1795 wxT(
"Undo the failed operation(s), then export or save your work and quit."));
1818(
BlockArray &additionalBlocks,
bool replaceLast,
1824 if (additionalBlocks.empty())
1827 bool tmpValid =
false;
1830 if ( replaceLast && !
mBlock.empty() ) {
1831 tmp =
mBlock.back(), tmpValid =
true;
1835 auto prevSize =
mBlock.size();
1837 bool consistent =
false;
1838 auto cleanup =
finally( [&] {
1839 if ( !consistent ) {
1840 mBlock.resize( prevSize );
1848 std::copy( additionalBlocks.begin(), additionalBlocks.end(),
1849 std::back_inserter(
mBlock ) );
1868 for (i = 0; i <
mBlock.size(); i++) {
1870 *dest += wxString::Format
1871 (
wxT(
" Block %3u: start %8lld, len %8lld, refs %ld, id %lld"),
1874 seqBlock.
sb ? (
long long) seqBlock.
sb->GetSampleCount() : 0,
1875 seqBlock.
sb ? seqBlock.
sb.use_count() : 0,
1876 seqBlock.
sb ? (
long long) seqBlock.
sb->GetBlockID() : 0);
1878 if ((pos != seqBlock.
start) || !seqBlock.
sb)
1879 *dest +=
wxT(
" ERROR\n");
1884 pos += seqBlock.
sb->GetSampleCount();
1887 *dest += wxString::Format
Toolkit-neutral facade for basic user interface services.
std::shared_ptr< SampleBlock > SampleBlockPtr
MessageBoxException for violation of preconditions or assertions.
#define CONSTRUCT_INCONSISTENCY_EXCEPTION
Construct InconsistencyException, using C++ preprocessor to identify the source code location.
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
std::shared_ptr< SampleBlockFactory > SampleBlockFactoryPtr
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
static constexpr auto Start_attr
static constexpr auto NumSamples_attr
static constexpr auto SampleFormat_attr
static constexpr auto EffectiveSampleFormat_attr
static constexpr auto MaxSamples_attr
std::vector< Attribute > AttributesList
static wxString ToString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, always uses the dot as decimal separator.
abstract base class with methods to produce SampleBlock objects
SampleBlockPtr Create(constSamplePtr src, size_t numsamples, sampleFormat srcformat)
SampleBuffer & Allocate(size_t count, sampleFormat format)
Data structure containing pointer to a sample block and a start time. Element of a BlockArray.
sampleCount start
the sample in the global wavetrack that this block starts at.
std::shared_ptr< SampleBlock > SampleBlockPtr
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
AudioSegmentSampleView GetFloatSampleView(sampleCount start, size_t len, bool mayThrow) const
static void SetMaxDiskBlockSize(size_t bytes)
void AppendBlocksIfConsistent(BlockArray &additionalBlocks, bool replaceLast, sampleCount numSamples, const wxChar *whereStr)
void AppendSharedBlock(const SeqBlock::SampleBlockPtr &pBlock)
Append a complete block, not coalescing.
size_t GetMaxBlockSize() const
SampleFormats GetSampleFormats() const
size_t GetBestBlockSize(sampleCount start) const
bool ConvertToSampleFormat(sampleFormat format, const std::function< void(size_t)> &progressReport={})
Sequence(const SampleBlockFactoryPtr &pFactory, SampleFormats formats)
void HandleXMLEndTag(const std::string_view &tag) override
SeqBlock::SampleBlockPtr AppendNewBlock(constSamplePtr buffer, sampleFormat format, size_t len)
void Delete(sampleCount start, sampleCount len)
void SetSamples(constSamplePtr buffer, sampleFormat format, sampleCount start, sampleCount len, sampleFormat effectiveFormat)
Pass nullptr to set silence.
void Paste(sampleCount s0, const Sequence *src)
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
std::unique_ptr< Sequence > Copy(const SampleBlockFactoryPtr &pFactory, sampleCount s0, sampleCount s1) const
void CommitChangesIfConsistent(BlockArray &newBlock, sampleCount numSamples, const wxChar *whereStr)
size_t GetIdealBlockSize() const
void ConsistencyCheck(const wxChar *whereStr, bool mayThrow=true) const
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool mayThrow) const
Get a range of samples from the sequence.
SampleBlockFactoryPtr mpFactory
static size_t sMaxDiskBlockSize
static const char * Sequence_tag
sampleFormat mAppendEffectiveFormat
void InsertSilence(sampleCount s0, sampleCount len)
void SetSilence(sampleCount s0, sampleCount len)
static void AppendBlock(SampleBlockFactory *pFactory, sampleFormat format, BlockArray &blocks, sampleCount &numSamples, const SeqBlock &b)
static size_t GetMaxDiskBlockSize()
sampleCount GetBlockStart(sampleCount position) const
static const char * WaveBlock_tag
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
static bool IsValidSampleFormat(const int nValue)
true if nValue is one of the sampleFormat enum values
std::atomic< size_t > mBlockCount
static bool Read(samplePtr buffer, sampleFormat format, const SeqBlock &b, size_t blockRelativeStart, size_t len, bool mayThrow)
float GetRMS(sampleCount start, sampleCount len, bool mayThrow) const
static void DebugPrintf(const BlockArray &block, sampleCount numSamples, wxString *dest)
SeqBlock::SampleBlockPtr DoAppend(constSamplePtr buffer, sampleFormat format, size_t len, bool coalesce)
Does not do any dithering.
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, size_t stride, sampleFormat effectiveFormat)
int FindBlock(sampleCount pos) const
static void Blockify(SampleBlockFactory &factory, size_t maxSamples, sampleFormat format, BlockArray &list, sampleCount start, constSamplePtr buffer, size_t len)
void WriteXML(XMLWriter &xmlFile) const
std::pair< float, float > GetMinMax(sampleCount start, sampleCount len, bool mayThrow) const
size_t GetIdealAppendLen() const
SampleBuffer mAppendBuffer
SampleFormats mSampleFormats
bool CloseLock() noexcept
Should be called upon project close. Not balanced by unlocking calls.
wxString Debug() const
Format as an English string for debugging logs and developers' eyes, not for end users.
This class is an interface which should be implemented by classes which wish to be able to load and s...
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Positions or offsets within audio files need a wide type.
long long as_long_long() const
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
void ensureSampleBufferSize(SampleBuffer &buffer, sampleFormat format, size_t &size, size_t required, SampleBuffer *pSecondBuffer=nullptr)
bool Overflows(double numSamples)
SampleBlockPtr ShareOrCopySampleBlock(SampleBlockFactory *pFactory, sampleFormat format, SampleBlockPtr sb)
__finl float_x4 __vecc sqrt(const float_x4 &a)
void copy(const T *src, T *dst, int32_t n)
MessageBoxOptions && Caption(TranslatableString caption_) &&