ElectroTechnique / TSynth-Teensy4.1

TSynth for Teensy 4.1
149 stars 41 forks source link

Oscilloscope updating speed #6

Closed ElectroTechnique closed 2 years ago

ElectroTechnique commented 3 years ago

Oscilloscope function needs more work to make updates faster. It's slowed by the zero crossing code that only updates when zero is crossed from positive to negative and then there is a delay while it looks for this again.

Would be nice to get it as good as Korg 'logue synths, with x-axis scaling to show whole waveform.

ElectroTechnique commented 2 years ago

Recent merge of improved code. Still not quite like Korg, but we're getting closer.

rolfdegen commented 2 years ago

Hello tsynth :) My idee for a better scope screen, I read 4 audio blocks and scaled them to the pixel width of the display.

#ifndef Oscilloscope_h_
#define Oscilloscope_h_
#include "AudioStream.h"
#include "ST7735_t3.h"

uint8_t bufferBlock = 0;
uint8_t bufcount = 0;
int16_t prev_pixel_y = 0;
const int lineColor = 0x07B0;
boolean EnvIdelFlag = false;

class Oscilloscope : public AudioStream {
    public:
    Oscilloscope(void) : AudioStream(1, inputQueueArray) {
    }
    virtual void update(void);
    void ScreenSetup(ST7735_t3*);
    void Display(void);
    void AddtoBuffer(int16_t*);

    private:
    audio_block_t *inputQueueArray[1];
    ST7735_t3 *display;
    int16_t buffer[AUDIO_BLOCK_SAMPLES];
};
#endif

void Oscilloscope::ScreenSetup(ST7735_t3 *screen) {
    display = screen;
}

void Oscilloscope::Display() {
    uint8_t pixel_x = 0;
    prev_pixel_y = map(buffer[0], 32767, -32768, -65, 65) + 95; // 1.Pixel to start drawing scope line
    if (prev_pixel_y < 65) prev_pixel_y = 65;
    if (prev_pixel_y > 126)prev_pixel_y = 126;
    for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES - 1; i++) {
        int16_t pixel_y = map(buffer[i], 32767, -32768, -65, 65) + 95;
        if (pixel_y < 65) pixel_y = 65;
        if (pixel_y > 126)pixel_y = 126;
        display->drawLine(pixel_x + 17, prev_pixel_y, pixel_x + 18, pixel_y, lineColor);
        prev_pixel_y = pixel_y;
        pixel_x++;
    }
}

// Scope scale 11.6ms For a better view at low frequencies
void Oscilloscope::AddtoBuffer(int16_t *audio) {
    int16_t prev_audio = 0;
    prev_audio = *audio;
    audio++;
    if (bufferBlock == 0) {
        if (prev_audio > 0 && *audio < 512) {       // change Scope Trigger for more screen refresh
            bufferBlock = 1;
            bufcount = 0;                           // ignore the first buffer block for trigger
        }
    }
    else {
        for (uint16_t i = 0; i < 32; i++) {
            buffer[bufcount++] = *audio;
            audio += 4;
        }
        bufferBlock++;
        if (bufferBlock >= 5) {
            bufferBlock = 0;
        }
    }
}

void Oscilloscope::update(void) {
    if (!display) return;
    audio_block_t *block;
    block = receiveReadOnly(0);
    if (block) {
        AddtoBuffer(block->data);
        release(block);
        if (bufferBlock == 0) {
            if (EnvIdelFlag == false) {  // is setting in the Main loop from Envelopes
                Display();
            }
        }

    }
}

Youtube: https://youtu.be/z1ktgjzEsYk?t=2449

ElectroTechnique commented 2 years ago

Thanks for this. I've been trying slightly different adjustments to the zero crossing code. I like the larger blocks with a sample added to the buffer every fourth sample. I found this improves stability of the wave (jumping from side to side):

void Oscilloscope::AddtoBuffer(int16_t *audio) {
  audio++;
  if (bufferBlock == 0) {
    if (*(audio-1) > -16 && *(audio+3) < 16) {  //<<<<<<<<<<<<<
      bufferBlock = 1;
     bufcount = 0;
    }
  }

Still some more work to do. A lot of implementations seem to hold the righthand side to zero and allow the wave to roll backwards.

I've been following this development, hoping to use his oscilloscope code, but it appears to be in assembly or something else compiled: https://www.youtube.com/watch?v=WJGOIgaY-1s

ElectroTechnique commented 2 years ago

I'm closing this issue because although it's not ideal yet, it does update faster and clearer than before.

rolfdegen commented 2 years ago

ok. Thanks for information. I will reconsider the scope code.