@@ -391,6 +391,16 @@ class LfpDisplayNodeLowRateTests : public LfpDisplayNodeTests
391391 }
392392};
393393
394+ class LfpDisplayNodeWideLowRatioTests : public LfpDisplayNodeTests
395+ {
396+ protected:
397+ void SetUp () override
398+ {
399+ sampleRate = 2500 .0f ;
400+ LfpDisplayNodeTests::SetUp ();
401+ }
402+ };
403+
394404// Checks if low sampling rate signals receive a sufficient buffer legnth
395405TEST_F (LfpDisplayNodeLowRateTests, LowRateDisplayBufferHasMinimumSize)
396406{
@@ -446,6 +456,99 @@ TEST_F (LfpDisplayNodeLowRateTests, LowRateSignalIsNotFlatLine)
446456 processor->stopAcquisition ();
447457}
448458
459+ TEST_F (LfpDisplayNodeLowRateTests, LowRateFirstSampleAdvancesScreenBuffer)
460+ {
461+ const int canvasX = 600 ;
462+ const int canvasY = 800 ;
463+
464+ std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
465+ std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE , false );
466+ canvas->updateSettings ();
467+ canvas->setSize (canvasX, canvasY);
468+ canvas->resized ();
469+ canvas->setVisible (true );
470+
471+ processor->startAcquisition ();
472+ canvas->beginAnimation ();
473+
474+ auto inputBuffer = createBufferSinusoidal (1 , numChannels, 1 , 100 );
475+ writeBlock (inputBuffer);
476+ canvas->refreshState ();
477+
478+ EXPECT_GT (canvas->getScreenBufferIndex (0 , 0 ), 0 )
479+ << " First low-rate sample was consumed without advancing the screen buffer" ;
480+
481+ processor->stopAcquisition ();
482+ }
483+
484+ TEST_F (LfpDisplayNodeWideLowRatioTests, WideDisplayCarriesLowRatioInterpolationPhase)
485+ {
486+ const int canvasX = 6000 ;
487+ const int canvasY = 800 ;
488+
489+ std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
490+ std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE , false );
491+ canvas->updateSettings ();
492+ canvas->setSize (canvasX, canvasY);
493+ canvas->resized ();
494+ canvas->setVisible (true );
495+
496+ processor->startAcquisition ();
497+ canvas->beginAnimation ();
498+
499+ auto firstSample = createBuffer (100 .0f , 0 .0f , numChannels, 1 );
500+ writeBlock (firstSample);
501+ canvas->refreshState ();
502+
503+ const int firstRefreshEnd = canvas->getScreenBufferIndex (0 , 0 );
504+
505+ auto secondSample = createBuffer (200 .0f , 0 .0f , numChannels, 1 );
506+ writeBlock (secondSample);
507+ canvas->refreshState ();
508+
509+ const float firstPixelAfterCarry = canvas->getScreenBufferMeanValue (0 , 0 , firstRefreshEnd);
510+ EXPECT_GT (firstPixelAfterCarry, 150 .0f )
511+ << " Low-ratio interpolation phase restarted instead of carrying across refreshes" ;
512+
513+ processor->stopAcquisition ();
514+ }
515+
516+ TEST_F (LfpDisplayNodeWideLowRatioTests, WideDisplayDoesNotDropPixelsNearOneSamplePerPixel)
517+ {
518+ const int canvasX = 4242 ;
519+ const int canvasY = 800 ;
520+ const int blockSamples = 50 ;
521+ const int numBlocks = 10 ;
522+ const float timebase = 2 .0f ;
523+
524+ std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
525+ std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE , false );
526+ canvas->updateSettings ();
527+ canvas->setSize (canvasX, canvasY);
528+ canvas->resized ();
529+ canvas->setVisible (true );
530+
531+ setExpectedImageParameters (canvas.get ());
532+
533+ processor->startAcquisition ();
534+ canvas->beginAnimation ();
535+
536+ for (int block = 0 ; block < numBlocks; ++block)
537+ {
538+ auto inputBuffer = createBuffer (100 .0f , 0 .0f , numChannels, blockSamples);
539+ writeBlock (inputBuffer);
540+ canvas->refreshState ();
541+ }
542+
543+ const float ratio = sampleRate * timebase / float (width);
544+ const int expectedPixels = int (float (blockSamples * numBlocks) / ratio);
545+
546+ EXPECT_GT (canvas->getScreenBufferIndex (0 , 0 ), expectedPixels - 5 )
547+ << " Samples were consumed without advancing enough screen-buffer pixels" ;
548+
549+ processor->stopAcquisition ();
550+ }
551+
449552// A connected trace produces signal in almost every pixel column; isolated dots produce
450553// signal in only ~numSamples columns. The midline band is excluded so a zero-buffer
451554// flat line scores zero columns.
0 commit comments