sync DDS and lockin FTWs
This commit is contained in:
parent
5991fa600d
commit
92ae6ae23c
30
fifo.h
Normal file
30
fifo.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
template<typename T, size_t N>
|
||||
class FIFO {
|
||||
private:
|
||||
size_t produce = 0;
|
||||
size_t consume = 0;
|
||||
bool empty = true;
|
||||
T storage[N];
|
||||
public:
|
||||
bool push(T x) {
|
||||
if(produce == consume && !empty)
|
||||
return false;
|
||||
storage[produce] = x;
|
||||
produce = (produce + 1) % N;
|
||||
empty = false;
|
||||
return true;
|
||||
}
|
||||
std::optional<T> pull() {
|
||||
if(empty)
|
||||
return std::nullopt;
|
||||
T ret = storage[consume];
|
||||
consume = (consume + 1) % N;
|
||||
if(produce == consume)
|
||||
empty = true;
|
||||
return ret;
|
||||
}
|
||||
};
|
30
sndlock.cpp
30
sndlock.cpp
@ -2,6 +2,7 @@
|
||||
#include <thread>
|
||||
#include <cstdint>
|
||||
#include <complex>
|
||||
#include <optional>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <sndio.h>
|
||||
@ -13,6 +14,7 @@
|
||||
#include "imgui_impl_opengl3.h"
|
||||
|
||||
#include "dsp_lib.h"
|
||||
#include "fifo.h"
|
||||
|
||||
#define SND_BITS 24
|
||||
#define SND_PCHAN 2
|
||||
@ -66,6 +68,11 @@ static void dsp_thread()
|
||||
int32_t buf_out[SND_BUFLEN*SND_PCHAN];
|
||||
size_t buf_out_offset = sizeof(buf_out);
|
||||
|
||||
int32_t buf_in[SND_BUFLEN*SND_RCHAN];
|
||||
size_t buf_in_offset = sizeof(buf_in);
|
||||
|
||||
FIFO<phase_t, 8> ftw_fifo[SND_PCHAN];
|
||||
|
||||
Lockin<4> lockin[SND_PCHAN];
|
||||
for(int i=0;i<SND_PCHAN;i++)
|
||||
// input channels are averaged together to reduce uncorrelated noise
|
||||
@ -79,15 +86,18 @@ static void dsp_thread()
|
||||
poll(pfd, nfds, INFTIM);
|
||||
int revents = sio_revents(hdl, pfd);
|
||||
|
||||
double lpf_k[SND_PCHAN];
|
||||
for(int i=0;i<SND_PCHAN;i++) {
|
||||
dds[i].ftw = lockin[i].ftw = frequency_to_ftw(frequency[i]/SND_RATE);
|
||||
for(int i=0;i<SND_PCHAN;i++)
|
||||
lockin[i].set_bandwidth(lpf_bandwidth[i]/SND_RATE);
|
||||
}
|
||||
|
||||
if(revents & POLLOUT) {
|
||||
double scale = pow(2.0, SND_BITS-1) - 1.0;
|
||||
if(buf_out_offset == sizeof(buf_out)) {
|
||||
for(int i=0;i<SND_PCHAN;i++) {
|
||||
phase_t ftw = frequency_to_ftw(frequency[i]/SND_RATE);
|
||||
dds[i].ftw = ftw;
|
||||
if(!ftw_fifo[i].push(ftw))
|
||||
std::cerr << "FTW FIFO overflow" << std::endl;
|
||||
}
|
||||
for(int i=0;i<SND_PCHAN;i++)
|
||||
for(int j=0;j<SND_BUFLEN;j++)
|
||||
buf_out[SND_PCHAN*j+i] = scale*dds[i].get();
|
||||
@ -98,8 +108,18 @@ static void dsp_thread()
|
||||
}
|
||||
|
||||
if(revents & POLLIN) {
|
||||
int32_t buf_in[SND_BUFLEN*SND_RCHAN];
|
||||
size_t read = sio_read(hdl, buf_in, sizeof(buf_in));
|
||||
buf_in_offset += read;
|
||||
if(buf_in_offset >= sizeof(buf_in)) {
|
||||
for(int i=0;i<SND_PCHAN;i++) {
|
||||
std::optional<phase_t> ftw = ftw_fifo[i].pull();
|
||||
if(ftw.has_value())
|
||||
lockin[i].ftw = ftw.value();
|
||||
else
|
||||
std::cerr << "FTW FIFO underflow" << std::endl;
|
||||
}
|
||||
buf_in_offset -= sizeof(buf_in);
|
||||
}
|
||||
for(int i=0;i<SND_PCHAN;i++)
|
||||
for(int j=0;j<read/(SND_RCHAN*sizeof(buf_in[0]));j++) {
|
||||
double sample = 0.0;
|
||||
|
Loading…
Reference in New Issue
Block a user