smoothing out the edges and bugs

This commit is contained in:
Ellen Arvidsson 2025-06-14 20:26:28 +02:00
parent f3a619decc
commit 67e4b2382b
3 changed files with 75 additions and 36 deletions

View file

@ -80,8 +80,6 @@ osclsk_scope::prep(void)
case osc_state::READY:
return (0);
case osc_state::RENDER_DONE:
block_fill = 0;
block_fill_nsamp = 0;
st = osc_state::READY;
return (0);
@ -95,11 +93,7 @@ osclsk_scope::trig(void)
{
switch (st) {
case osc_state::READY:
trig_lkb_idx = 0;
trig_lkb_idx_nsamp = 0;
trig_num = 0;
trig_state = osc_trig_state::READY;
st = osc_state::TRIGGER;
@ -162,11 +156,23 @@ osclsk_scope::sample(const float *sig, size_t num)
}
}
if (block_fill >= OSCLSK_BLOCK_LEN)
if (block_fill >= OSCLSK_BLOCK_LEN) {
st = osc_state::SAMPLE_DONE;
/* use the leftover samples to sample the trig lookback
* data buffer. we reset the nsamp for the current
* lookback buffer index to get a clean slate */
trig_lkb_idx_nsamp = 0;
trig_lkb_num = 0;
sample_trigger(&sig[i], num - i);
}
break;
case osc_state::TRIGGER:
case osc_state::SAMPLE_DONE:
case osc_state::RENDER:
case osc_state::RENDER_DONE:
case osc_state::READY:
sample_trigger(sig, num);
break;
default:
@ -174,13 +180,18 @@ osclsk_scope::sample(const float *sig, size_t num)
}
}
bool
osclsk_scope::is_triggering(float sample)
{
switch (trig_mode) {
case osc_trig_mode::RISING_EDGE:
return (sample > trig_margin);
case osc_trig_mode::FALLING_EDGE:
return (sample < -trig_margin);
case osc_trig_mode::ABS_THRESHOLD:
return (std::abs(sample) > trig_margin);
case osc_trig_mode::INSTANT:
return (true);
default:
return (false);
}
@ -191,10 +202,11 @@ osclsk_scope::trig_lkb_wr_block(void)
{
size_t lkb_i, n;
lkb_i = trig_lkb_idx > trig_lkb_amount ?
trig_lkb_idx - trig_lkb_amount :
OSCLSK_TRIG_LOOKBACK + trig_lkb_idx - trig_lkb_amount;
lkb_i = trig_lkb_idx >= trig_lkb_amount ?
trig_lkb_idx - (trig_lkb_amount) :
OSCLSK_TRIG_LOOKBACK + trig_lkb_idx - (trig_lkb_amount);
block_fill = 0;
for (n = 0; n < trig_lkb_amount; n++) {
block_y_max[block_fill] = trig_lkb_y_max[lkb_i];
block_y_min[block_fill] = trig_lkb_y_min[lkb_i];
@ -216,7 +228,7 @@ osclsk_scope::sample_trigger(const float *sig, size_t num)
{
size_t i;
AC_PRECOND(st == osc_state::TRIGGER);
AC_PRECOND(st != osc_state::INIT && st != osc_state::SAMPLE);
/* sample data in lookback buffers */
for (i = 0; i < num; i++) {
@ -238,38 +250,62 @@ osclsk_scope::sample_trigger(const float *sig, size_t num)
trig_lkb_idx_nsamp = 0;
}
trig_lkb_num = std::min(trig_lkb_num + 1,
OSCLSK_TRIG_LOOKBACK);
trig_lkb_idx =
trig_lkb_idx & (OSCLSK_TRIG_LOOKBACK - 1);
}
/* do triggering checks */
/* only do triggering checks in TRIGGER state and out lookback buffer is
* full enough */
if (st != osc_state::TRIGGER || trig_lkb_num < trig_lkb_amount)
return;
/* trigger needs to be in NO_TRIG before TRIG state for e.g.
* RISING_EDGE trigger mode */
for (i = 0; i < num; i++) {
switch (trig_state) {
case osc_trig_state::READY:
if (! is_triggering(sig[i])) {
trig_state = osc_trig_state::NO_TRIG;
switch (trig_mode) {
case osc_trig_mode::RISING_EDGE:
case osc_trig_mode::FALLING_EDGE:
case osc_trig_mode::ABS_THRESHOLD:
if (! is_triggering(sig[i])) {
trig_state = osc_trig_state::NO_TRIG;
}
break;
case osc_trig_mode::INSTANT:
trig_state = osc_trig_state::TRIGGERED;
break;
}
break;
case osc_trig_state::NO_TRIG:
if (is_triggering(sig[i])) {
trig_num = 0;
trig_num++;
trig_state = osc_trig_state::TRIG;
}
break;
case osc_trig_state::TRIG:
if (is_triggering(sig[i])) {
if (++trig_num >= trig_num_req) {
trig_state =
osc_trig_state::TRIGGERED;
}
trig_num++;
} else {
trig_state = osc_trig_state::NO_TRIG;
trig_num = 0;
}
break;
default:
break;
}
if (trig_num >= trig_num_req) {
trig_state =
osc_trig_state::TRIGGERED;
}
if (trig_state == osc_trig_state::TRIGGERED)
break;
}
/* transfer lookback to actual block if triggered */
@ -336,11 +372,11 @@ osclsk_scope::render_block(void)
}
for (render_idx = 0; render_idx < OSCLSK_BLOCK_LEN;
render_idx++) {
screen_px_y_max[render_idx] = 1u + (uint16_t)(
OSCLSK_Y_MAX_PX * (.5f + block_y_max[render_idx])
screen_px_y_max[render_idx] = (uint16_t)(
OSCLSK_Y_MAX_PX/2 * (1 - block_y_max[render_idx])
);
screen_px_y_min[render_idx] = (uint16_t)(
OSCLSK_Y_MAX_PX * (.5f + block_y_min[render_idx])
screen_px_y_min[render_idx] = 1u + (uint16_t)(
OSCLSK_Y_MAX_PX/2 * (1 - block_y_min[render_idx])
);
}
@ -359,9 +395,10 @@ osclsk_scope::render_block(void)
case osc_state::RENDER:
for (; render_idx < OSCLSK_BLOCK_LEN; render_idx++) {
res = tft.async_hline_row_bg_fill(async_id, &bg, &fg,
screen_px_y_min[render_idx],
screen_px_y_max[render_idx],
screen_px_y_max[render_idx], // inverted
screen_px_y_min[render_idx], // inverted
render_idx);
AC_ASSERT(res >= 0);
if (res < 0)
return (-1);
if (res > 0)

View file

@ -15,7 +15,7 @@ using namespace daisy;
#define OSCLSK_RATE_DIV 32
#define OSCLSK_BLOCK_LEN OSCLSK_SCREEN_XSZ
#define OSCLSK_TRIG_LOOKBACK 0x100
#define OSCLSK_TRIG_LOOKBACK 0x100u
#define OSCLSK_TFT_CMD_BUF_NSPLIT 4
@ -40,6 +40,7 @@ struct osclsk_scope {
RISING_EDGE,
FALLING_EDGE,
ABS_THRESHOLD,
INSTANT
};
enum class osc_trig_state {
@ -61,6 +62,7 @@ struct osclsk_scope {
float trig_lkb_y_min[OSCLSK_TRIG_LOOKBACK];
size_t trig_lkb_idx;
int trig_lkb_idx_nsamp;
size_t trig_lkb_num;
size_t trig_lkb_amount;
float trig_margin;
@ -85,10 +87,10 @@ struct osclsk_scope {
block_fill(0), block_fill_nsamp(0),
trig_lkb_idx(0), trig_lkb_idx_nsamp(0),
trig_lkb_amount(2),
trig_margin(.05f), trig_num(0),
trig_margin(.01f), trig_num(0),
trig_num_req(2),
trig_state(osc_trig_state::INIT),
trig_mode(osc_trig_mode::RISING_EDGE),
trig_mode(osc_trig_mode::INSTANT),
render_idx(0) {};
int init(uint8_t *dma_buf, size_t dma_sz);

View file

@ -163,13 +163,6 @@ main(void)
while (true) {
read = scope_in.readable();
read = (read <= sizeof(s)/sizeof(*s)) ? read :
sizeof(s)/sizeof(*s);
scope_in.ImmediateRead(s, read);
scope.sample(s, read);
switch (scope.state()) {
case osclsk_scope::osc_state::SAMPLE_DONE:
@ -188,6 +181,13 @@ main(void)
break;
}
read = scope_in.readable();
read = (read <= sizeof(s)/sizeof(*s)) ? read :
sizeof(s)/sizeof(*s);
scope_in.ImmediateRead(s, read);
scope.sample(s, read);
// if (--load_tick == 0) {
// load_tick = LOAD_METER_TICKS;
// // get the current load (smoothed value and peak values)