diff --git a/oscope-of/src/HantekDevice.cpp b/oscope-of/src/HantekDevice.cpp index 0064fac..afbb51c 100644 --- a/oscope-of/src/HantekDevice.cpp +++ b/oscope-of/src/HantekDevice.cpp @@ -167,8 +167,15 @@ void HantekDevice::stop() { void HantekDevice::setSampleRate(uint32_t hz) { sampleRateHz_.store(hz); if (handle_ != nullptr && running_.load()) { - const uint8_t code = sampleRateCode(hz); + // Le FX2 (firmware OpenHantek6022) attend la séquence : stop (0xE3=0) + // → set sample rate (0xE2) → start (0xE3=1). Sans le re-start, le + // bulk endpoint cesse d'émettre et le stream se fige. + const uint8_t stopTrig = 0x00; + const uint8_t code = sampleRateCode(hz); + const uint8_t startTrig = 0x01; + sendVendorControl(0xE3, 0, 0, &stopTrig, 1); sendVendorControl(kReqSetSampleRate, 0, 0, &code, 1); + sendVendorControl(0xE3, 0, 0, &startTrig, 1); } } diff --git a/oscope-of/src/visualizers/WaveformVis.cpp b/oscope-of/src/visualizers/WaveformVis.cpp index 475f3ac..7efbcad 100644 --- a/oscope-of/src/visualizers/WaveformVis.cpp +++ b/oscope-of/src/visualizers/WaveformVis.cpp @@ -9,10 +9,11 @@ void WaveformVis::setup(int w, int h) { h_ = h; trace1_.assign(syntheticSize_, 0.0f); trace2_.assign(syntheticSize_, 0.0f); - // Ring d'historique : ~16x la fenêtre pour pouvoir scroller en arrière - // sans trou même avec un timebase lent. - ring1_.assign(syntheticSize_ * 16, 0.0f); - ring2_.assign(syntheticSize_ * 16, 0.0f); + // Ring d'historique : assez grand pour que le timebase puisse aller + // jusqu'à ~125 ms à 8 MS/s (ou 1 s à 1 MS/s). 1 M floats ≈ 4 Mo par + // canal, soit 8 Mo total — acceptable pour une vue scope live. + ring1_.assign(1 << 20, 0.0f); + ring2_.assign(1 << 20, 0.0f); ringHead_ = 0; } @@ -42,12 +43,13 @@ void WaveformVis::update(const VisFrame& frame) { if (scrollSpeed_ < 0.01f) return; // Largeur de la fenêtre = timebase × divisions, convertie en samples. - // (sampleRate * (ms/div × divX) / 1000) + // (sampleRate * (ms/div × divX) / 1000). On NE clamp PAS à + // trace1_.size() : on downsample lors du remplissage du trace, ce + // qui rend le slider timebase réellement effectif. const float winSec = (timeMsPerDiv_ * 0.001f) * divX_; std::size_t winSamples = static_cast( std::max(64.0f, std::min(static_cast(cap), winSec * sampleRateHz_))); - winSamples = std::min(winSamples, trace1_.size()); // Position de lecture : tail = head - winSamples (mode freeze) ou // tail décalé pour un effet de scroll continu.