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( [&] {
371 assert(t->IsLeader());
377 uint64_t nChunks, chunkSize;
379 chunkSize = 200ull + (rand() % 100ull);
380 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
381 while (nChunks < 20 || chunkSize > (blockSize*1024)/4)
383 chunkSize = std::max( uint64_t(1), (chunkSize / 2) + (rand() % 100) );
384 nChunks = (dataSize * 1048576ull) / (chunkSize*
sizeof(
SampleType));
391 Printf(
XO(
"Using %lld chunks of %lld samples each, for a total of %.1f MB.\n")
392 .
Format( nChunks, chunkSize, nChunks*chunkSize*
sizeof(
SampleType)/1048576.0 ) );
394 int trials = numEdits;
397 Samples small1{nChunks};
398 Samples block{chunkSize};
412 for (uint64_t i = 0; i < nChunks; i++) {
415 for (uint64_t b = 0; b < chunkSize; b++)
427 if (t->GetClipByIndex(0)->GetVisibleSampleCount() != nChunks * chunkSize) {
428 Printf(
XO(
"Expected len %lld, track len %lld.\n")
431 t->GetClipByIndex(0)->GetVisibleSampleCount()
441 for (z = 0; z < trials; z++) {
444 const uint64_t x0 = rand() % nChunks;
448 const uint64_t xlen = 1 + (rand() % (nChunks - x0));
451 .
Format( x0 * chunkSize, (x0 + xlen) * chunkSize) );
456 t->Cut(
double (x0 * chunkSize),
double ((x0 + xlen) * chunkSize));
460 Printf(
XO(
"Cut (%lld, %lld) failed.\n")
461 .
Format( (x0 * chunkSize), (x0 + xlen) * chunkSize) );
462 Printf(
XO(
"Expected len %lld, track len %lld.\n")
465 t->GetClipByIndex(0)->GetVisibleSampleCount()
472 const uint64_t y0 = rand() % (nChunks - xlen + 1);
478 t->Paste((
double)(y0 * chunkSize), *tmp);
485 if (t->GetClipByIndex(0)->GetVisibleSampleCount() != nChunks * chunkSize) {
487 Printf(
XO(
"Expected len %lld, track len %lld.\n")
490 t->GetClipByIndex(0)->GetVisibleSampleCount()
496 auto first = &small1[0];
497 if (x0 + xlen < nChunks)
498 std::rotate( first + x0, first + x0 + xlen, first + nChunks );
499 std::rotate( first + y0, first + nChunks - xlen, first + nChunks );
502 elapsed = timer.Time();
505 auto seq = t->GetClipByIndex(0)->GetSequence(0);
506 seq->DebugPrintf(seq->GetBlockArray(), seq->GetNumSamples(), &tempStr);
509 Printf(
XO(
"Time to perform %d edits: %ld ms\n").
Format( trials, elapsed ) );
515 Printf(
XO(
"Checking file pointer leaks:\n") );
516 Printf(
XO(
"Track # blocks: %ld\n").
Format( t->GetBlockArray()->size() ) );
518 system(
"ls .audacity_temp/* | wc --lines");
521 Printf(
XO(
"Doing correctness check...\n") );
527 for (uint64_t i = 0; i < nChunks; i++) {
529 auto pBlock =
reinterpret_cast<samplePtr>(block.get());
530 constexpr auto backwards =
false;
531 t->Get(0, 1, &pBlock,
SampleFormat, i * chunkSize, chunkSize, backwards);
532 for (uint64_t b = 0; b < chunkSize; b++)
541 Printf(
XO(
"Passed correctness check!\n") );
543 Printf(
XO(
"Errors in %d/%lld chunks\n").
Format( bad, nChunks ) );
545 elapsed = timer.Time();
547 Printf(
XO(
"Time to check all data: %ld ms\n").
Format( elapsed ) );
548 Printf(
XO(
"Reading data again...\n") );
555 for (uint64_t i = 0; i < nChunks; i++) {
557 auto pBlock =
reinterpret_cast<samplePtr>(block.get());
558 constexpr auto backwards =
false;
559 t->Get(0, 1, &pBlock,
SampleFormat, i * chunkSize, chunkSize, backwards);
560 for (uint64_t b = 0; b < chunkSize; b++)
565 elapsed = timer.Time();
567 Printf(
XO(
"Time to check all data (2): %ld ms\n").
Format( elapsed ) );
569 Printf(
XO(
"At 44100 Hz, %d bytes per sample, the estimated number of\n simultaneous tracks that could be played at once: %.1f\n" )
579 Printf(
XO(
"Benchmark completed successfully.\n") );
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
static AudioUnitEffectsModule::Factory::SubstituteInUnique< AudioUnitEffect > scope
void RunBenchmark(wxWindow *parent, AudacityProject &project)
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)
std::shared_ptr< TrackList > TrackListHolder
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.
static TrackListHolder Temporary(AudacityProject *pProject, const Track::Holder &left={}, const Track::Holder &right={})
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...