Audacity  2.2.2
BlockFile.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  BlockFile.cpp
6 
7  Joshua Haberman
8  Dominic Mazzoni
9 
10 *******************************************************************//****************************************************************//*******************************************************************/
41 
42 #include "Audacity.h"
43 #include "BlockFile.h"
44 
45 #include <float.h>
46 #include <cmath>
47 
48 #include <wx/utils.h>
49 #include <wx/filefn.h>
50 #include <wx/ffile.h>
51 #include <wx/log.h>
52 
53 #include "Internat.h"
54 #include "MemoryX.h"
55 #include "sndfile.h"
56 #include "FileFormats.h"
57 #include "AudacityApp.h"
58 
59 // msmeyer: Define this to add debug output via wxPrintf()
60 //#define DEBUG_BLOCKFILE
61 
62 #ifdef DEBUG_BLOCKFILE
63 #define BLOCKFILE_DEBUG_OUTPUT(op, i) \
64  wxPrintf(wxT("[BlockFile %x %s] %s: %i\n"), (unsigned)this, \
65  mFileName.GetFullName(), wxT(op), i);
66 #else
67 #define BLOCKFILE_DEBUG_OUTPUT(op, i)
68 #endif
69 
70 static const int headerTagLen = 20;
71 static char headerTag[headerTagLen + 1] = "AudacityBlockFile112";
72 
73 SummaryInfo::SummaryInfo(size_t samples)
74 {
76 
77  fields = 3; /* min, max, rms */
78 
79  bytesPerFrame = sizeof(float) * fields;
80 
81  frames64K = (samples + 65535) / 65536;
82  frames256 = frames64K * 256;
83 
87 }
88 
90 
101 BlockFile::BlockFile(wxFileNameWrapper &&fileName, size_t samples):
102  mLockCount(0),
103  mFileName(std::move(fileName)),
104  mLen(samples),
105  mSummaryInfo(samples)
106 {
107  mSilentLog=FALSE;
108 }
109 
110 // static
111 unsigned long BlockFile::gBlockFileDestructionCount { 0 };
112 
114 {
115  if (!IsLocked() && mFileName.HasName())
116  // PRL: what should be done if this fails?
117  wxRemoveFile(mFileName.GetFullPath());
118 
120 }
121 
128 {
129  return { mFileName };
130 }
131 
134 {
135  mFileName=std::move(name);
136 }
137 
138 
149 {
150  mLockCount++;
152 }
153 
156 {
157  mLockCount--;
159 }
160 
163 {
164  return mLockCount > 0;
165 }
166 
181 void *BlockFile::CalcSummary(samplePtr buffer, size_t len,
183 {
184  // Caller has nothing to deallocate
185  cleanup.reset();
186 
188 
189  memcpy(fullSummary.get(), headerTag, headerTagLen);
190 
191  float *summary64K = (float *)(fullSummary.get() + mSummaryInfo.offset64K);
192  float *summary256 = (float *)(fullSummary.get() + mSummaryInfo.offset256);
193 
194  Floats fbuffer{ len };
195  CopySamples(buffer, format,
196  (samplePtr)fbuffer.get(), floatSample, len);
197 
198  CalcSummaryFromBuffer(fbuffer.get(), len, summary256, summary64K);
199 
200  return fullSummary.get();
201 }
202 
203 void BlockFile::CalcSummaryFromBuffer(const float *fbuffer, size_t len,
204  float *summary256, float *summary64K)
205 {
206  decltype(len) sumLen;
207 
208  float min, max;
209  float sumsq;
210  double totalSquares = 0.0;
211  double fraction { 0.0 };
212 
213  // Recalc 256 summaries
214  sumLen = (len + 255) / 256;
215  int summaries = 256;
216 
217  for (decltype(sumLen) i = 0; i < sumLen; i++) {
218  min = fbuffer[i * 256];
219  max = fbuffer[i * 256];
220  sumsq = ((float)min) * ((float)min);
221  decltype(len) jcount = 256;
222  if (jcount > len - i * 256) {
223  jcount = len - i * 256;
224  fraction = 1.0 - (jcount / 256.0);
225  }
226  for (decltype(jcount) j = 1; j < jcount; j++) {
227  float f1 = fbuffer[i * 256 + j];
228  sumsq += ((float)f1) * ((float)f1);
229  if (f1 < min)
230  min = f1;
231  else if (f1 > max)
232  max = f1;
233  }
234 
235  totalSquares += sumsq;
236  float rms = (float)sqrt(sumsq / jcount);
237 
238  summary256[i * 3] = min;
239  summary256[i * 3 + 1] = max;
240  summary256[i * 3 + 2] = rms; // The rms is correct, but this may be for less than 256 samples in last loop.
241  }
242  for (auto i = sumLen; i < mSummaryInfo.frames256; i++) {
243  // filling in the remaining bits with non-harming/contributing values
244  // rms values are not "non-harming", so keep count of them:
245  summaries--;
246  summary256[i * 3] = FLT_MAX; // min
247  summary256[i * 3 + 1] = -FLT_MAX; // max
248  summary256[i * 3 + 2] = 0.0f; // rms
249  }
250 
251  // Calculate now while we can do it accurately
252  mRMS = sqrt(totalSquares/len);
253 
254  // Recalc 64K summaries
255  sumLen = (len + 65535) / 65536;
256 
257  for (decltype(sumLen) i = 0; i < sumLen; i++) {
258  min = summary256[3 * i * 256];
259  max = summary256[3 * i * 256 + 1];
260  sumsq = (float)summary256[3 * i * 256 + 2];
261  sumsq *= sumsq;
262  for (decltype(len) j = 1; j < 256; j++) { // we can overflow the useful summary256 values here, but have put non-harmful values in them
263  if (summary256[3 * (i * 256 + j)] < min)
264  min = summary256[3 * (i * 256 + j)];
265  if (summary256[3 * (i * 256 + j) + 1] > max)
266  max = summary256[3 * (i * 256 + j) + 1];
267  float r1 = summary256[3 * (i * 256 + j) + 2];
268  sumsq += r1*r1;
269  }
270 
271  double denom = (i < sumLen - 1) ? 256.0 : summaries - fraction;
272  float rms = (float)sqrt(sumsq / denom);
273 
274  summary64K[i * 3] = min;
275  summary64K[i * 3 + 1] = max;
276  summary64K[i * 3 + 2] = rms;
277  }
278  for (auto i = sumLen; i < mSummaryInfo.frames64K; i++) {
279  wxASSERT_MSG(false, wxT("Out of data for mSummaryInfo")); // Do we ever get here?
280  summary64K[i * 3] = 0.0f; // probably should be FLT_MAX, need a test case
281  summary64K[i * 3 + 1] = 0.0f; // probably should be -FLT_MAX, need a test case
282  summary64K[i * 3 + 2] = 0.0f; // just padding
283  }
284 
285  // Recalc block-level summary (mRMS already calculated)
286  min = summary64K[0];
287  max = summary64K[1];
288 
289  for (decltype(sumLen) i = 1; i < sumLen; i++) {
290  if (summary64K[3*i] < min)
291  min = summary64K[3*i];
292  if (summary64K[3*i+1] > max)
293  max = summary64K[3*i+1];
294  }
295 
296  mMin = min;
297  mMax = max;
298 }
299 
300 static void ComputeMinMax256(float *summary256,
301  float *outMin, float *outMax, int *outBads)
302 {
303  float min, max;
304  int i;
305  int bad = 0;
306 
307  min = 1.0;
308  max = -1.0;
309  for(i=0; i<256; i++) {
310  if (summary256[3*i] < min)
311  min = summary256[3*i];
312  else if (!(summary256[3*i] >= min))
313  bad++;
314  if (summary256[3*i+1] > max)
315  max = summary256[3*i+1];
316  else if (!(summary256[3*i+1] <= max))
317  bad++;
318  if (std::isnan(summary256[3*i+2]))
319  bad++;
320  if (summary256[3*i+2] < -1 || summary256[3*i+2] > 1)
321  bad++;
322  }
323 
324  *outMin = min;
325  *outMax = max;
326  *outBads = bad;
327 }
328 
331 void BlockFile::FixSummary(void *data)
332 {
334  mSummaryInfo.fields != 3)
335  return;
336 
337  float *summary64K = (float *)((char *)data + mSummaryInfo.offset64K);
338  float *summary256 = (float *)((char *)data + mSummaryInfo.offset256);
339 
340  float min, max;
341  int bad;
342 
343  ComputeMinMax256(summary256, &min, &max, &bad);
344 
345  if (min != summary64K[0] || max != summary64K[1] || bad > 0) {
346  unsigned int *buffer = (unsigned int *)data;
347  auto len = mSummaryInfo.totalSummaryBytes / 4;
348 
349  for(unsigned int i=0; i<len; i++)
350  buffer[i] = wxUINT32_SWAP_ALWAYS(buffer[i]);
351 
352  ComputeMinMax256(summary256, &min, &max, &bad);
353  if (min == summary64K[0] && max == summary64K[1] && bad == 0) {
354  // The byte-swapping worked!
355  return;
356  }
357 
358  // Hmmm, no better, we should swap back
359  for(unsigned i=0; i<len; i++)
360  buffer[i] = wxUINT32_SWAP_ALWAYS(buffer[i]);
361  }
362 }
363 
369 auto BlockFile::GetMinMaxRMS(size_t start, size_t len, bool mayThrow)
370  const -> MinMaxRMS
371 {
372  // TODO: actually use summaries
373  SampleBuffer blockData(len, floatSample);
374 
375  this->ReadData(blockData.ptr(), floatSample, start, len, mayThrow);
376 
377  float min = FLT_MAX;
378  float max = -FLT_MAX;
379  float sumsq = 0;
380 
381  for( decltype(len) i = 0; i < len; i++ )
382  {
383  float sample = ((float*)blockData.ptr())[i];
384 
385  if( sample > max )
386  max = sample;
387  if( sample < min )
388  min = sample;
389  sumsq += (sample*sample);
390  }
391 
392  return { min, max, (float)sqrt(sumsq/len) };
393 }
394 
399  const -> MinMaxRMS
400 {
401  return { mMin, mMax, mRMS };
402 }
403 
415 bool BlockFile::Read256(float *buffer,
416  size_t start, size_t len)
417 {
418  wxASSERT(start >= 0);
419 
420  ArrayOf< char > summary;
421  // In case of failure, summary is filled with zeroes
422  auto result = this->ReadSummary(summary);
423 
424  start = std::min( start, mSummaryInfo.frames256 );
425  len = std::min( len, mSummaryInfo.frames256 - start );
426 
427  CopySamples(summary.get() + mSummaryInfo.offset256 +
428  (start * mSummaryInfo.bytesPerFrame),
430  (samplePtr)buffer, floatSample, len * mSummaryInfo.fields);
431 
432  if (mSummaryInfo.fields == 2) {
433  // No RMS info; make guess
434  for(auto i = len; i--;) {
435  buffer[3*i+2] = (fabs(buffer[2*i]) + fabs(buffer[2*i+1]))/4.0;
436  buffer[3*i+1] = buffer[2*i+1];
437  buffer[3*i] = buffer[2*i];
438  }
439  }
440 
441  return result;
442 }
443 
454 bool BlockFile::Read64K(float *buffer,
455  size_t start, size_t len)
456 {
457  wxASSERT(start >= 0);
458 
459  ArrayOf< char > summary;
460  // In case of failure, summary is filled with zeroes
461  auto result = this->ReadSummary(summary);
462 
463  start = std::min( start, mSummaryInfo.frames64K );
464  len = std::min( len, mSummaryInfo.frames64K - start );
465 
466  CopySamples(summary.get() + mSummaryInfo.offset64K +
467  (start * mSummaryInfo.bytesPerFrame),
469  (samplePtr)buffer, floatSample, len * mSummaryInfo.fields);
470 
471  if (mSummaryInfo.fields == 2) {
472  // No RMS info; make guess
473  for(auto i = len; i--;) {
474  buffer[3*i+2] = (fabs(buffer[2*i]) + fabs(buffer[2*i+1]))/4.0;
475  buffer[3*i+1] = buffer[2*i+1];
476  buffer[3*i] = buffer[2*i];
477  }
478  }
479 
480  return result;
481 }
482 
484  bool mayThrow,
485  const wxFileName &fileName, bool &mSilentLog,
486  const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
487  samplePtr data, sampleFormat format, size_t start, size_t len,
488  const sampleFormat *pLegacyFormat, size_t legacyLen)
489 {
490  // Third party library has its own type alias, check it before
491  // adding origin + size_t
492  static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
493  "Type sf_count_t is too narrow to hold a sampleCount");
494 
495  SF_INFO info;
496  memset(&info, 0, sizeof(info));
497 
498  if ( pLegacyFormat ) {
499  switch( *pLegacyFormat ) {
500  case int16Sample:
501  info.format =
502  SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_CPU;
503  break;
504  default:
505  case floatSample:
506  info.format =
507  SF_FORMAT_RAW | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
508  break;
509  case int24Sample:
510  info.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32 | SF_ENDIAN_CPU;
511  break;
512  }
513  info.samplerate = 44100; // Doesn't matter
514  info.channels = 1;
515  info.frames = legacyLen + origin.as_long_long();
516  }
517 
518 
519  wxFile f; // will be closed when it goes out of scope
520  SFFile sf;
521 
522  {
523  Maybe<wxLogNull> silence{};
524  if (mSilentLog)
525  silence.create();
526 
527  const auto fullPath = fileName.GetFullPath();
528  if (wxFile::Exists(fullPath) && f.Open(fullPath)) {
529  // Even though there is an sf_open() that takes a filename, use the one that
530  // takes a file descriptor since wxWidgets can open a file with a Unicode name and
531  // libsndfile can't (under Windows).
532  sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
533  }
534 
535  if (!sf) {
536 
537  memset(data, 0, SAMPLE_SIZE(format)*len);
538 
539  if (pAliasFile) {
540  // Set a marker to display an error message for the silence
541  if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
543  }
544  }
545  }
546  mSilentLog = !sf;
547 
548  size_t framesRead = 0;
549  if (sf) {
550  auto seek_result = SFCall<sf_count_t>(
551  sf_seek, sf.get(), ( origin + start ).as_long_long(), SEEK_SET);
552 
553  if (seek_result < 0)
554  // error
555  ;
556  else {
557  auto channels = info.channels;
558  wxASSERT(channels >= 1);
559  wxASSERT((int)channel < channels);
560 
561  if (channels == 1 &&
562  format == int16Sample &&
563  sf_subtype_is_integer(info.format)) {
564  // If both the src and dest formats are integer formats,
565  // read integers directly from the file, comversions not needed
566  framesRead = SFCall<sf_count_t>(
567  sf_readf_short, sf.get(), (short *)data, len);
568  }
569  else if (channels == 1 &&
570  format == int24Sample &&
571  sf_subtype_is_integer(info.format)) {
572  framesRead = SFCall<sf_count_t>(
573  sf_readf_int, sf.get(), (int *)data, len);
574 
575  // libsndfile gave us the 3 byte sample in the 3 most
576  // significant bytes -- we want it in the 3 least
577  // significant bytes.
578  int *intPtr = (int *)data;
579  for( size_t i = 0; i < framesRead; i++ )
580  intPtr[i] = intPtr[i] >> 8;
581  }
582  else if (format == int16Sample &&
583  !sf_subtype_more_than_16_bits(info.format)) {
584  // Special case: if the file is in 16-bit (or less) format,
585  // and the calling method wants 16-bit data, go ahead and
586  // read 16-bit data directly. This is a pretty common
587  // case, as most audio files are 16-bit.
588  SampleBuffer buffer(len * channels, int16Sample);
589  framesRead = SFCall<sf_count_t>(
590  sf_readf_short, sf.get(), (short *)buffer.ptr(), len);
591  for (size_t i = 0; i < framesRead; i++)
592  ((short *)data)[i] =
593  ((short *)buffer.ptr())[(channels * i) + channel];
594  }
595  else {
596  // Otherwise, let libsndfile handle the conversion and
597  // scaling, and pass us normalized data as floats. We can
598  // then convert to whatever format we want.
599  SampleBuffer buffer(len * channels, floatSample);
600  framesRead = SFCall<sf_count_t>(
601  sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
602  auto bufferPtr = (samplePtr)((float *)buffer.ptr() + channel);
603  CopySamples(bufferPtr, floatSample,
604  (samplePtr)data, format,
605  framesRead,
606  true /* high quality by default */,
607  channels /* source stride */);
608  }
609  }
610  }
611 
612  if ( framesRead < len ) {
613  if (mayThrow)
614  throw FileException{ FileException::Cause::Read, fileName };
615  ClearSamples(data, format, framesRead, len - framesRead);
616  }
617 
618  return framesRead;
619 }
620 
641  wxFileNameWrapper &&aliasedFileName,
642  sampleCount aliasStart,
643  size_t aliasLen, int aliasChannel):
644  BlockFile {
645  (baseFileName.SetExt(wxT("auf")), std::move(baseFileName)),
646  aliasLen
647  },
648  mAliasedFileName(std::move(aliasedFileName)),
649  mAliasStart(aliasStart),
650  mAliasChannel(aliasChannel)
651 {
652  mSilentAliasLog=FALSE;
653 }
654 
656  wxFileNameWrapper &&aliasedFileName,
657  sampleCount aliasStart,
658  size_t aliasLen,
659  int aliasChannel,
660  float min, float max, float rms):
661  BlockFile{ std::move(existingSummaryFileName), aliasLen },
662  mAliasedFileName(std::move(aliasedFileName)),
663  mAliasStart(aliasStart),
664  mAliasChannel(aliasChannel)
665 {
666  mMin = min;
667  mMax = max;
668  mRMS = rms;
669  mSilentAliasLog=FALSE;
670 }
676 {
677  // To build the summary data, call ReadData (implemented by the
678  // derived classes) to get the sample data
679  // Call this first, so that in case of exceptions from ReadData, there is
680  // no NEW output file
681  SampleBuffer sampleData(mLen, floatSample);
682  this->ReadData(sampleData.ptr(), floatSample, 0, mLen);
683 
684  // Now checked carefully in the DirManager
685  //wxASSERT( !wxFileExists(FILENAME(mFileName.GetFullPath())));
686 
687  // I would much rather have this code as part of the constructor, but
688  // I can't call virtual functions from the constructor. So we just
689  // need to ensure that every derived class calls this in *its* constructor
690  wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb"));
691 
692  if( !summaryFile.IsOpened() ){
693  // Never silence the Log w.r.t write errors; they always count
694  // as NEW errors
695  wxLogError(wxT("Unable to write summary data to file %s"),
696  mFileName.GetFullPath());
697  // If we can't write, there's nothing to do.
698  return;
699  }
700 
701  ArrayOf<char> cleanup;
702  void *summaryData = BlockFile::CalcSummary(sampleData.ptr(), mLen,
703  floatSample, cleanup);
704  summaryFile.Write(summaryData, mSummaryInfo.totalSummaryBytes);
705 }
706 
708 {
709 }
710 
718 {
720  wxFFile summaryFile(mFileName.GetFullPath(), wxT("rb"));
721 
722  {
723  Maybe<wxLogNull> silence{};
724  if (mSilentLog)
725  silence.create();
726 
727  if (!summaryFile.IsOpened()){
728 
729  // NEW model; we need to return valid data
730  memset(data.get(), 0, mSummaryInfo.totalSummaryBytes);
731 
732  // we silence the logging for this operation in this object
733  // after first occurrence of error; it's already reported and
734  // spewing at the user will complicate the user's ability to
735  // deal
736  mSilentLog = TRUE;
737  return false;
738 
739  }
740  else mSilentLog = FALSE; // worked properly, any future error is NEW
741  }
742 
743  auto read = summaryFile.Read(data.get(), mSummaryInfo.totalSummaryBytes);
744  if (read != mSummaryInfo.totalSummaryBytes) {
745  memset(data.get(), 0, mSummaryInfo.totalSummaryBytes);
746  return false;
747  }
748 
749  FixSummary(data.get());
750 
751  return true;
752 }
753 
758 {
759  mAliasedFileName = std::move(newAliasedFile);
760 }
761 
763 {
764  wxFFile summaryFile(mFileName.GetFullPath());
765  return summaryFile.Length();
766 }
767 
int bytesPerFrame
Definition: BlockFile.h:36
sampleFormat format
Definition: BlockFile.h:35
const int mAliasChannel
Definition: BlockFile.h:291
A BlockFile is a chunk of immutable audio data.
Definition: BlockFile.h:56
static unsigned long gBlockFileDestructionCount
Definition: BlockFile.h:65
wxFileNameWrapper mFileName
Definition: BlockFile.h:235
void CalcSummaryFromBuffer(const float *fbuffer, size_t len, float *summary256, float *summary64K)
Definition: BlockFile.cpp:203
size_t frames256
Definition: BlockFile.h:39
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:117
int offset64K
Definition: BlockFile.h:38
void CopySamples(samplePtr src, sampleFormat srcFormat, samplePtr dst, sampleFormat dstFormat, unsigned int len, bool highQuality, unsigned int srcStride, unsigned int dstStride)
bool sf_subtype_more_than_16_bits(unsigned int format)
static const int headerTagLen
Definition: BlockFile.cpp:70
#define SAMPLE_SIZE(SampleFormat)
Definition: Types.h:198
bool mSilentLog
Definition: BlockFile.h:239
Definition: MemoryX.h:204
bool ReadSummary(ArrayOf< char > &data) override
Read the summary into a buffer.
Definition: BlockFile.cpp:717
SummaryInfo mSummaryInfo
Definition: BlockFile.h:237
BlockFile(wxFileNameWrapper &&fileName, size_t samples)
Construct a BlockFile.
Definition: BlockFile.cpp:101
virtual bool Read256(float *buffer, size_t start, size_t len)
Returns the 256 byte summary data block.
Definition: BlockFile.cpp:415
float mMin
Definition: BlockFile.h:238
wxFileNameWrapper mAliasedFileName
Definition: BlockFile.h:289
virtual bool IsLocked()
Returns TRUE if this BlockFile is locked.
Definition: BlockFile.cpp:162
long long type
Definition: Types.h:63
virtual bool ReadSummary(ArrayOf< char > &data)=0
Read the summary section of the file. Derived classes implement.
AliasBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&aliasedFileName, sampleCount aliasStart, size_t aliasLen, int aliasChannel)
Constructs an AliasBlockFile.
Definition: BlockFile.cpp:640
unsigned long long DiskByteCount
Definition: BlockFile.h:152
static char headerTag[headerTagLen+1]
Definition: BlockFile.cpp:71
int format
Definition: ExportPCM.cpp:56
virtual ~BlockFile()
Definition: BlockFile.cpp:113
void ChangeAliasedFileName(wxFileNameWrapper &&newAliasedFile)
Definition: BlockFile.cpp:757
SummaryInfo(size_t samples)
Definition: BlockFile.cpp:73
sampleFormat
Definition: Types.h:188
bool sf_subtype_is_integer(unsigned int format)
#define BLOCKFILE_DEBUG_OUTPUT(op, i)
Definition: BlockFile.cpp:67
float mRMS
Definition: BlockFile.h:238
char * samplePtr
Definition: Types.h:203
size_t totalSummaryBytes
Definition: BlockFile.h:41
virtual void Lock()
Locks this BlockFile, to prevent it from being moved.
Definition: BlockFile.cpp:148
int min(int a, int b)
samplePtr ptr() const
Definition: SampleFormat.h:81
bool mSilentAliasLog
Definition: BlockFile.h:292
sampleCount mAliasStart
Definition: BlockFile.h:290
size_t mLen
Definition: BlockFile.h:236
virtual void * CalcSummary(samplePtr buffer, size_t len, sampleFormat format, ArrayOf< char > &cleanup)
Definition: BlockFile.cpp:181
static size_t CommonReadData(bool mayThrow, const wxFileName &fileName, bool &mSilentLog, const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel, samplePtr data, sampleFormat format, size_t start, size_t len, const sampleFormat *pLegacyFormat=nullptr, size_t legacyLen=0)
Definition: BlockFile.cpp:483
virtual void SetFileName(wxFileNameWrapper &&name)
sets the file name the summary info will be saved in. threadsafe.
Definition: BlockFile.cpp:133
int fields
Definition: BlockFile.h:34
size_t frames64K
Definition: BlockFile.h:37
virtual ~AliasBlockFile()
Definition: BlockFile.cpp:707
DiskByteCount GetSpaceUsage() const override
Definition: BlockFile.cpp:762
virtual void Unlock()
Unlock this BlockFile, allowing it to be moved.
Definition: BlockFile.cpp:155
static ArrayOf< char > fullSummary
Definition: BlockFile.h:232
const wxChar * name
Definition: Distortion.cpp:94
void MarkAliasedFilesMissingWarning(const AliasBlockFile *b)
Mark playback as having missing aliased blockfiles.
virtual GetFileNameResult GetFileName() const
Definition: BlockFile.cpp:127
void ClearSamples(samplePtr dst, sampleFormat format, size_t start, size_t len)
A BlockFile that refers to data in an existing file.
Definition: BlockFile.h:251
long long as_long_long() const
Definition: Types.h:90
virtual MinMaxRMS GetMinMaxRMS(size_t start, size_t len, bool mayThrow=true) const
Gets extreme values for the specified region.
Definition: BlockFile.cpp:369
static void ComputeMinMax256(float *summary256, float *outMin, float *outMax, int *outBads)
Definition: BlockFile.cpp:300
int mLockCount
Definition: BlockFile.h:230
virtual void WriteSummary()
Write the summary to disk, using the derived ReadData() to get the data.
Definition: BlockFile.cpp:675
virtual size_t ReadData(samplePtr data, sampleFormat format, size_t start, size_t len, bool mayThrow=true) const =0
int offset256
Definition: BlockFile.h:40
float mMax
Definition: BlockFile.h:238
AudacityApp & wxGetApp()
virtual void FixSummary(void *data)
Definition: BlockFile.cpp:331
void create(Args &&...args)
Definition: MemoryX.h:251
virtual bool Read64K(float *buffer, size_t start, size_t len)
Returns the 64K summary data block.
Definition: BlockFile.cpp:454