23#include <wx/textctrl.h>
24#include <wx/checkbox.h>
26#include <wx/stattext.h>
27#include <wx/stopwatch.h>
29#include <wx/valtext.h>
47#define SampleType short
48#define SampleFormat int16Sample
60 void OnRun( wxCommandEvent &event );
61 void OnSave( wxCommandEvent &event );
62 void OnClear( wxCommandEvent &event );
63 void OnClose( wxCommandEvent &event );
107 dlog.CentreOnParent();
139 wxDefaultPosition, wxDefaultSize,
140 wxDEFAULT_DIALOG_STYLE |
147 mBlockSizeStr =
wxT(
"64");
148 mNumEditsStr =
wxT(
"100");
149 mDataSizeStr =
wxT(
"32");
150 mRandSeedStr =
wxT(
"234657");
152 mBlockDetail =
false;
157 MakeBenchmarkDialog();
174 S.StartVerticalLay(
true);
177 S.StartMultiColumn(4);
181 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mBlockSizeStr)
182 .AddTextBox(
XXO(
"Disk Block Size (KB):"),
188 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mNumEditsStr)
189 .AddTextBox(
XXO(
"Number of Edits:"),
195 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mDataSizeStr)
196 .AddTextBox(
XXO(
"Test Data Size (MB):"),
202 .Validator<wxTextValidator>(wxFILTER_NUMERIC, &
mRandSeedStr)
205 .AddTextBox(
XXO(
"Random Seed:"),
214 .AddCheckBox(
XXO(
"Show detailed info about each block file"),
219 .AddCheckBox(
XXO(
"Show detailed info about each editing operation"),
226 .Style( wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH )
227 .MinSize( { 500, 200 } )
228 .AddTextWindow(
wxT(
""));
232 S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND,
false);
234 S.StartHorizontalLay(wxALIGN_LEFT,
false);
236 S.Id(
RunID).AddButton(
XXO(
"Run"), wxALIGN_CENTRE,
true);
241 S.EndHorizontalLay();
243 S.StartHorizontalLay(wxALIGN_CENTER,
true);
247 S.EndHorizontalLay();
249 S.StartHorizontalLay(wxALIGN_NOT | wxALIGN_LEFT,
false);
252 S.Id(wxID_CANCEL).AddButton(
XXO(
"Close"));
254 S.EndHorizontalLay();
256 S.EndHorizontalLay();
261 SetSizeHints(GetSize());
268 auto fName =
XO(
"benchmark.txt").Translation();
270 fName =
SelectFile(FileNames::Operation::Export,
271 XO(
"Export Benchmark Data as:"),
276 wxFD_SAVE | wxRESIZE_BORDER,
282 mText->SaveFile(fName);
292 auto s =
str.Translation();
319 TransferDataFromWindow();
326 long blockSize, numEdits, dataSize, randSeed;
333 if (blockSize < 1 || blockSize > 1024) {
335 XO(
"Block size should be in the range 1 - 1024 KB.") );
339 if (numEdits < 1 || numEdits > 10000) {
341 XO(
"Number of edits should be in the range 1 - 10000.") );
345 if (dataSize < 1 || dataSize > 2000) {
347 XO(
"Test data size should be in the range 1 - 2000 MB.") );
358 const auto cleanup =
finally( [&] {
375 uint64_t nChunks, chunkSize;
377 chunkSize = 200ull + (rand() % 100ull);
378 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
379 while (nChunks < 20 || chunkSize > (blockSize*1024)/4)
381 chunkSize = std::max( uint64_t(1), (chunkSize / 2) + (rand() % 100) );
382 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
389 Printf(
XO(
"Using %lld chunks of %lld samples each, for a total of %.1f MB.\n")
390 .
Format( nChunks, chunkSize, nChunks*chunkSize*
sizeof(
SampleType)/1048576.0 ) );
392 int trials = numEdits;
395 Samples small1{nChunks};
396 Samples block{chunkSize};
410 for (uint64_t i = 0; i < nChunks; i++) {
413 for (uint64_t b = 0; b < chunkSize; b++)
425 if (t->GetClipByIndex(0)->GetPlaySamplesCount() != nChunks * chunkSize) {
426 Printf(
XO(
"Expected len %lld, track len %lld.\n")
429 t->GetClipByIndex(0)->GetPlaySamplesCount()
439 for (z = 0; z < trials; z++) {
442 const uint64_t x0 = rand() % nChunks;
446 const uint64_t xlen = 1 + (rand() % (nChunks - x0));
449 .
Format( x0 * chunkSize, (x0 + xlen) * chunkSize) );
453 tmp = t->Cut(
double (x0 * chunkSize),
double ((x0 + xlen) * chunkSize));
457 Printf(
XO(
"Cut (%lld, %lld) failed.\n")
458 .
Format( (x0 * chunkSize), (x0 + xlen) * chunkSize) );
459 Printf(
XO(
"Expected len %lld, track len %lld.\n")
462 t->GetClipByIndex(0)->GetPlaySamplesCount()
469 const uint64_t y0 = rand() % (nChunks - xlen + 1);
475 t->Paste((
double)(y0 * chunkSize), tmp.get());
482 if (t->GetClipByIndex(0)->GetPlaySamplesCount() != nChunks * chunkSize) {
484 Printf(
XO(
"Expected len %lld, track len %lld.\n")
487 t->GetClipByIndex(0)->GetPlaySamplesCount()
493 auto first = &small1[0];
494 if (x0 + xlen < nChunks)
495 std::rotate( first + x0, first + x0 + xlen, first + nChunks );
496 std::rotate( first + y0, first + nChunks - xlen, first + nChunks );
499 elapsed = timer.Time();
502 auto seq = t->GetClipByIndex(0)->GetSequence();
503 seq->DebugPrintf(seq->GetBlockArray(), seq->GetNumSamples(), &tempStr);
506 Printf(
XO(
"Time to perform %d edits: %ld ms\n").
Format( trials, elapsed ) );
512 Printf(
XO(
"Checking file pointer leaks:\n") );
513 Printf(
XO(
"Track # blocks: %ld\n").
Format( t->GetBlockArray()->size() ) );
515 system(
"ls .audacity_temp/* | wc --lines");
518 Printf(
XO(
"Doing correctness check...\n") );
524 for (uint64_t i = 0; i < nChunks; i++) {
527 for (uint64_t b = 0; b < chunkSize; b++)
536 Printf(
XO(
"Passed correctness check!\n") );
538 Printf(
XO(
"Errors in %d/%lld chunks\n").
Format( bad, nChunks ) );
540 elapsed = timer.Time();
542 Printf(
XO(
"Time to check all data: %ld ms\n").
Format( elapsed ) );
543 Printf(
XO(
"Reading data again...\n") );
550 for (uint64_t i = 0; i < nChunks; i++) {
553 for (uint64_t b = 0; b < chunkSize; b++)
558 elapsed = timer.Time();
560 Printf(
XO(
"Time to check all data (2): %ld ms\n").
Format( elapsed ) );
562 Printf(
XO(
"At 44100 Hz, %d bytes per sample, the estimated number of\n simultaneous tracks that could be played at once: %.1f\n" )
572 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
XXO("&Cut/Copy/Paste Toolbar")
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
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
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...