New paste Repaste Download
// struct definition, shared with UI
struct rb_compute_buffers {
  uint8_t channels;
  uint16_t nframes;
  float buffers[16][2048]; // very generous worst case of 2048 buffer size and 16 channels to display on the scope
};
// dsp init
#define DEFAULT_RB_SIZE 1048608 // also very generous, >1MB allocated to make sure there's always room for the dsp thread to write to the ring buffer
ringbuffer_t *rb;
// ...
rb = ringbuffer_create(DEFAULT_RB_SIZE);
// dsp thread
virtual void processAudio(jack_nframes_t nframes)
        {
            // Audio
            AVOIDDENORMALS;
            
            // Retrieve JACK inputs/output audio buffers
            float** fInChannel = (float**)alloca(fInputPorts.size() * sizeof(float*));
            for (size_t i = 0; i < fInputPorts.size(); i++) {
                fInChannel[i] = (float*)jack_port_get_buffer(fInputPorts[i], nframes);
            }
            
            float** fOutChannel = (float**)alloca(fOutputPorts.size() * sizeof(float*));
            for (size_t i = 0; i < fOutputPorts.size(); i++) {
                fOutChannel[i] = (float*)jack_port_get_buffer(fOutputPorts[i], nframes);
            }
            
            // By convention timestamp of -1 means 'no timestamp conversion', events already have a timestamp expressed in frames
            fDSP->compute(-1, nframes, reinterpret_cast<FAUSTFLOAT**>(fInChannel), reinterpret_cast<FAUSTFLOAT**>(fOutChannel));
            
            rb_compute_buffers rb_buffer;
            rb_buffer.nframes = nframes;
            rb_buffer.channels = fOutputPorts.size();
            for (size_t i = 0; i < fOutputPorts.size(); i++) {
              memcpy(rb_buffer.buffers[i], fOutChannel[i], nframes * sizeof(float));
            }
            if (ringbuffer_write_space(rb) >= sizeof(rb_buffer))
            {
              size_t written = ringbuffer_write(rb, (void*)&rb_buffer, sizeof(rb_buffer));
            }
}
// UI thread
// ...
static constexpr size_t scope_buffer_length = 48000; // One second by default
float scope_buffer[16][scope_buffer_length]; // <- this is the buffer the UI can use
size_t scope_buffer_sizeof = scope_buffer_length * sizeof(float);
// ...
while (size_t available = ringbuffer_read_space(rb))
        {
          if (available >= sizeof(rb_compute_buffers))
          {
            rb_compute_buffers recv;
            size_t read = ringbuffer_read(rb, (void*)&recv, sizeof(rb_compute_buffers));
            size_t nframes_sizeof = recv.nframes * sizeof(float);
            for (size_t i = 0; i < recv.channels; i++) {
              memmove(scope_buffer[i], &scope_buffer[i][recv.nframes], scope_buffer_sizeof - nframes_sizeof);
              memcpy(&scope_buffer[i][scope_buffer_length - recv.nframes], recv.buffers[i], nframes_sizeof);
            }
          }
        }
// ...
Filename: None. Size: 3kb. View raw, , hex, or download this file.

This paste expires on 2024-06-02 14:08:41.703186. Pasted through web.