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 <thread>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <sndio.h>
|
#include <sndio.h>
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "imgui_impl_opengl3.h"
|
#include "imgui_impl_opengl3.h"
|
||||||
|
|
||||||
#include "dsp_lib.h"
|
#include "dsp_lib.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
#define SND_BITS 24
|
#define SND_BITS 24
|
||||||
#define SND_PCHAN 2
|
#define SND_PCHAN 2
|
||||||
@ -66,6 +68,11 @@ static void dsp_thread()
|
|||||||
int32_t buf_out[SND_BUFLEN*SND_PCHAN];
|
int32_t buf_out[SND_BUFLEN*SND_PCHAN];
|
||||||
size_t buf_out_offset = sizeof(buf_out);
|
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];
|
Lockin<4> lockin[SND_PCHAN];
|
||||||
for(int i=0;i<SND_PCHAN;i++)
|
for(int i=0;i<SND_PCHAN;i++)
|
||||||
// input channels are averaged together to reduce uncorrelated noise
|
// input channels are averaged together to reduce uncorrelated noise
|
||||||
@ -79,15 +86,18 @@ static void dsp_thread()
|
|||||||
poll(pfd, nfds, INFTIM);
|
poll(pfd, nfds, INFTIM);
|
||||||
int revents = sio_revents(hdl, pfd);
|
int revents = sio_revents(hdl, pfd);
|
||||||
|
|
||||||
double lpf_k[SND_PCHAN];
|
for(int i=0;i<SND_PCHAN;i++)
|
||||||
for(int i=0;i<SND_PCHAN;i++) {
|
|
||||||
dds[i].ftw = lockin[i].ftw = frequency_to_ftw(frequency[i]/SND_RATE);
|
|
||||||
lockin[i].set_bandwidth(lpf_bandwidth[i]/SND_RATE);
|
lockin[i].set_bandwidth(lpf_bandwidth[i]/SND_RATE);
|
||||||
}
|
|
||||||
|
|
||||||
if(revents & POLLOUT) {
|
if(revents & POLLOUT) {
|
||||||
double scale = pow(2.0, SND_BITS-1) - 1.0;
|
double scale = pow(2.0, SND_BITS-1) - 1.0;
|
||||||
if(buf_out_offset == sizeof(buf_out)) {
|
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 i=0;i<SND_PCHAN;i++)
|
||||||
for(int j=0;j<SND_BUFLEN;j++)
|
for(int j=0;j<SND_BUFLEN;j++)
|
||||||
buf_out[SND_PCHAN*j+i] = scale*dds[i].get();
|
buf_out[SND_PCHAN*j+i] = scale*dds[i].get();
|
||||||
@ -98,8 +108,18 @@ static void dsp_thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(revents & POLLIN) {
|
if(revents & POLLIN) {
|
||||||
int32_t buf_in[SND_BUFLEN*SND_RCHAN];
|
|
||||||
size_t read = sio_read(hdl, buf_in, sizeof(buf_in));
|
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 i=0;i<SND_PCHAN;i++)
|
||||||
for(int j=0;j<read/(SND_RCHAN*sizeof(buf_in[0]));j++) {
|
for(int j=0;j<read/(SND_RCHAN*sizeof(buf_in[0]));j++) {
|
||||||
double sample = 0.0;
|
double sample = 0.0;
|
||||||
|
Loading…
Reference in New Issue
Block a user