23#include <wx/textctrl.h>
25#include <wx/checkbox.h>
29#include <wx/stattext.h>
33#include <wx/valtext.h>
53#define SampleType short
54#define SampleFormat int16Sample
66 void OnRun( wxCommandEvent &event );
67 void OnSave( wxCommandEvent &event );
68 void OnClear( wxCommandEvent &event );
69 void OnClose( wxCommandEvent &event );
113 dlog.CentreOnParent();
145 wxDefaultPosition, wxDefaultSize,
146 wxDEFAULT_DIALOG_STYLE |
153 mBlockSizeStr = wxT(
"64");
154 mNumEditsStr = wxT(
"100");
155 mDataSizeStr = wxT(
"32");
156 mRandSeedStr = wxT(
"234657");
158 mBlockDetail =
false;
163 MakeBenchmarkDialog();
180 S.StartVerticalLay(
true);
183 S.StartMultiColumn(4);
187 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mBlockSizeStr)
188 .AddTextBox(
XXO(
"Disk Block Size (KB):"),
194 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mNumEditsStr)
195 .AddTextBox(
XXO(
"Number of Edits:"),
201 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mDataSizeStr)
202 .AddTextBox(
XXO(
"Test Data Size (MB):"),
208 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mRandSeedStr)
211 .AddTextBox(
XXO(
"Random Seed:"),
220 .AddCheckBox(
XXO(
"Show detailed info about each block file"),
225 .AddCheckBox(
XXO(
"Show detailed info about each editing operation"),
232 .Style( wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH )
233 .MinSize( { 500, 200 } )
234 .AddTextWindow(wxT(
""));
238 S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND,
false);
240 S.StartHorizontalLay(wxALIGN_LEFT,
false);
242 S.Id(
RunID).AddButton(
XXO(
"Run"), wxALIGN_CENTRE,
true);
247 S.EndHorizontalLay();
249 S.StartHorizontalLay(wxALIGN_CENTER,
true);
253 S.EndHorizontalLay();
255 S.StartHorizontalLay(wxALIGN_NOT | wxALIGN_LEFT,
false);
258 S.Id(wxID_CANCEL).AddButton(
XXO(
"Close"));
260 S.EndHorizontalLay();
262 S.EndHorizontalLay();
267 SetSizeHints(GetSize());
274 auto fName =
XO(
"benchmark.txt").Translation();
276 fName =
SelectFile(FileNames::Operation::Export,
277 XO(
"Export Benchmark Data as:"),
282 wxFD_SAVE | wxRESIZE_BORDER,
288 mText->SaveFile(fName);
298 auto s =
str.Translation();
325 TransferDataFromWindow();
332 long blockSize, numEdits, dataSize, randSeed;
339 if (blockSize < 1 || blockSize > 1024) {
341 XO(
"Block size should be in the range 1 - 1024 KB.") );
345 if (numEdits < 1 || numEdits > 10000) {
347 XO(
"Number of edits should be in the range 1 - 10000.") );
351 if (dataSize < 1 || dataSize > 2000) {
353 XO(
"Test data size should be in the range 1 - 2000 MB.") );
364 const auto cleanup =
finally( [&] {
381 uint64_t nChunks, chunkSize;
383 chunkSize = 200ull + (rand() % 100ull);
384 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
385 while (nChunks < 20 || chunkSize > (blockSize*1024)/4)
387 chunkSize = std::max( uint64_t(1), (chunkSize / 2) + (rand() % 100) );
388 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
395 Printf(
XO(
"Using %lld chunks of %lld samples each, for a total of %.1f MB.\n")
396 .
Format( nChunks, chunkSize, nChunks*chunkSize*
sizeof(
SampleType)/1048576.0 ) );
398 int trials = numEdits;
401 Samples small1{nChunks};
402 Samples block{chunkSize};
416 for (uint64_t i = 0; i < nChunks; i++) {
419 for (uint64_t b = 0; b < chunkSize; b++)
431 if (t->GetClipByIndex(0)->GetSequence()->GetNumSamples() != nChunks * chunkSize) {
432 Printf(
XO(
"Expected len %lld, track len %lld.\n")
435 t->GetClipByIndex(0)->GetSequence()->GetNumSamples()
445 for (z = 0; z < trials; z++) {
448 const uint64_t x0 = rand() % nChunks;
452 const uint64_t xlen = 1 + (rand() % (nChunks - x0));
455 .
Format( x0 * chunkSize, (x0 + xlen) * chunkSize) );
459 tmp = t->Cut(
double (x0 * chunkSize),
double ((x0 + xlen) * chunkSize));
463 Printf(
XO(
"Cut (%lld, %lld) failed.\n")
464 .
Format( (x0 * chunkSize), (x0 + xlen) * chunkSize) );
465 Printf(
XO(
"Expected len %lld, track len %lld.\n")
468 t->GetClipByIndex(0)->GetSequence()->GetNumSamples()
475 const uint64_t y0 = rand() % (nChunks - xlen + 1);
481 t->Paste((
double)(y0 * chunkSize), tmp.get());
488 if (t->GetClipByIndex(0)->GetSequence()->GetNumSamples() != nChunks * chunkSize) {
490 Printf(
XO(
"Expected len %lld, track len %lld.\n")
493 t->GetClipByIndex(0)->GetSequence()->GetNumSamples()
499 auto first = &small1[0];
500 if (x0 + xlen < nChunks)
501 std::rotate( first + x0, first + x0 + xlen, first + nChunks );
502 std::rotate( first + y0, first + nChunks - xlen, first + nChunks );
505 elapsed = timer.Time();
508 auto seq = t->GetClipByIndex(0)->GetSequence();
509 seq->DebugPrintf(seq->GetBlockArray(), seq->GetNumSamples(), &tempStr);
512 Printf(
XO(
"Time to perform %d edits: %ld ms\n").
Format( trials, elapsed ) );
518 Printf(
XO(
"Checking file pointer leaks:\n") );
519 Printf(
XO(
"Track # blocks: %ld\n").
Format( t->GetBlockArray()->size() ) );
521 system(
"ls .audacity_temp/* | wc --lines");
524 Printf(
XO(
"Doing correctness check...\n") );
530 for (uint64_t i = 0; i < nChunks; i++) {
533 for (uint64_t b = 0; b < chunkSize; b++)
542 Printf(
XO(
"Passed correctness check!\n") );
544 Printf(
XO(
"Errors in %d/%lld chunks\n").
Format( bad, nChunks ) );
546 elapsed = timer.Time();
548 Printf(
XO(
"Time to check all data: %ld ms\n").
Format( elapsed ) );
549 Printf(
XO(
"Reading data again...\n") );
556 for (uint64_t i = 0; i < nChunks; i++) {
559 for (uint64_t b = 0; b < chunkSize; b++)
564 elapsed = timer.Time();
566 Printf(
XO(
"Time to check all data (2): %ld ms\n").
Format( elapsed ) );
568 Printf(
XO(
"At 44100 Hz, %d bytes per sample, the estimated number of\n simultaneous tracks that could be played at once: %.1f\n" )
578 Printf(
XO(
"Benchmark completed successfully.\n") );
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
void RunBenchmark(wxWindow *parent, AudacityProject &project)
static TransactionScope::Factory::Scope scope
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
an object holding per-project preferred sample rate
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
BoolSetting EditClipsCanMove
Memory.h template class for making an array of float, bool, etc.
Base class for exceptions specially processed by the application.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
BenchmarkDialog is used for measuring performance and accuracy of sample block storage.
void OnClose(wxCommandEvent &event)
void OnSave(wxCommandEvent &event)
void HoldPrint(bool hold)
BenchmarkDialog(wxWindow *parent, AudacityProject &project)
void OnClear(wxCommandEvent &event)
AudacityProject & mProject
void Printf(const TranslatableString &str)
void MakeBenchmarkDialog()
void OnRun(wxCommandEvent &event)
const ProjectRate & mRate
FILES_API const FileType TextFiles
Holds project sample rate.
static ProjectRate & Get(AudacityProject &project)
static SampleBlockFactoryPtr New(AudacityProject &project)
static void SetMaxDiskBlockSize(size_t bytes)
static size_t GetMaxDiskBlockSize()
bool Write(const T &value)
Write value to config and return true if successful.
Makes temporary changes to preferences, then rolls them back at destruction.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
std::shared_ptr< Track > Holder
Holds a msgid for the translation catalog; may also bind format arguments.
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...