Compare commits

...

4 Commits

2 changed files with 59 additions and 12 deletions

View File

@ -2,6 +2,8 @@
#include <cstdint>
#include <complex>
#include <chrono>
#include <thread>
typedef uint32_t phase_t;
#define PHASE_MAX UINT32_MAX
@ -71,3 +73,23 @@ class Lockin {
return phase;
}
};
class Clocker {
private:
std::chrono::milliseconds period;
std::chrono::time_point<std::chrono::steady_clock> next_tick = std::chrono::time_point<std::chrono::steady_clock>::min();
public:
Clocker(std::chrono::milliseconds period): period(period) {};
void tick() {
if(next_tick == std::chrono::time_point<std::chrono::steady_clock>::min()) {
next_tick = std::chrono::steady_clock::now() + period;
} else {
auto duration = next_tick - std::chrono::steady_clock::now();
if(duration >= duration.zero())
std::this_thread::sleep_for(duration);
else
std::cerr << "missed tick" << std::endl;
next_tick += period;
}
}
};

View File

@ -3,6 +3,7 @@
#include <cstdint>
#include <complex>
#include <optional>
#include <chrono>
#include <GLFW/glfw3.h>
#include <sndio.h>
@ -37,8 +38,10 @@ static float in_wave[HIST_DEPTH];
static std::atomic<int> multiplier[SND_PCHAN];
static std::atomic<double> lpf_bandwidth[SND_PCHAN];
static std::atomic<double> li_mag[SND_PCHAN];
static std::atomic<double> li_phase[SND_PCHAN];
static std::mutex li_hist_mutex;
static std::atomic<bool> li_hist_pause[SND_PCHAN];
static std::atomic<bool> li_hist_hold[SND_PCHAN];
static float li_hist_mag[SND_PCHAN][HIST_DEPTH];
static float li_hist_phase[SND_PCHAN][HIST_DEPTH];
@ -86,7 +89,7 @@ static void dsp_thread()
int32_t buf_in[SND_BUFLEN*SND_RCHAN];
size_t buf_in_offset = sizeof(buf_in);
FIFO<phase_t, 16> ftw_fifo[SND_PCHAN];
FIFO<phase_t, 32> ftw_fifo[SND_PCHAN];
int clipped_count = 0;
double peak_running = 0.0;
@ -201,16 +204,20 @@ static void dsp_thread()
for(int j=0;j<SND_PCHAN;j++) {
std::complex<double> lockin_out = lockin[j].update(sample);
double mag = std::abs(lockin_out);
double phase = std::arg(lockin_out);
if(!li_hist_pause[j]) {
li_mag[j] = mag;
li_phase[j] = phase;
if(!li_hist_hold[j]) {
li_count[j]++;
if(li_count[j] == 200) {
li_count[j] = 0;
std::lock_guard<std::mutex> guard(li_hist_mutex);
std::memmove(&li_hist_mag[j][0], &li_hist_mag[j][1], (HIST_DEPTH-1)*sizeof(float));
li_hist_mag[j][HIST_DEPTH-1] = std::abs(lockin_out);
li_hist_mag[j][HIST_DEPTH-1] = mag;
std::memmove(&li_hist_phase[j][0], &li_hist_phase[j][1], (HIST_DEPTH-1)*sizeof(float));
li_hist_phase[j][HIST_DEPTH-1] = std::arg(lockin_out);
li_hist_phase[j][HIST_DEPTH-1] = phase;
}
}
}
@ -228,6 +235,15 @@ static void dsp_thread()
sio_close(hdl);
}
static void servo_thread(int channel)
{
Clocker clocker = Clocker(std::chrono::milliseconds(100));
while(!shutdown_threads) {
clocker.tick();
std::cout << "servo thread tick " << channel << std::endl;
}
}
int main(int argc, char* argv[])
{
if(!glfwInit()) {
@ -237,7 +253,7 @@ int main(int argc, char* argv[])
std::atexit(glfwTerminate);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
static GLFWwindow* window = glfwCreateWindow(1024, 1200, "sndlock", nullptr, nullptr);
static GLFWwindow *window = glfwCreateWindow(1024, 1200, "Soundlocker", nullptr, nullptr);
if(window == nullptr) {
std::cerr << "failed to create GLFW window" << std::endl;
return 1;
@ -276,6 +292,15 @@ int main(int argc, char* argv[])
};
std::atexit(JoinDSP);
static std::thread servo_thread_h[SND_PCHAN];
for(int i=0;i<SND_PCHAN;i++)
servo_thread_h[i] = std::thread(servo_thread, i);
static auto JoinServo = []() {
for(int i=0;i<SND_PCHAN;i++)
servo_thread_h[i].join();
};
std::atexit(JoinServo);
shutdown_threads = false;
static auto SetShutdown = []() {
shutdown_threads = true;
@ -297,7 +322,7 @@ int main(int argc, char* argv[])
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
ImGui::SetNextWindowSize(io.DisplaySize);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::Begin("sndlock", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
ImGui::Begin("Soundlocker", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
if(ImGui::CollapsingHeader("Modulation")) {
for(int i=0;i<SND_PCHAN;i++) {
@ -360,11 +385,11 @@ int main(int argc, char* argv[])
multiplier[i] = multiplier_l;
ImGui::SameLine();
ImGui::Text("/");
bool pause_l = li_hist_pause[i];
bool hold_l = li_hist_hold[i];
ImGui::SameLine();
sprintf(str, "pause##%d", i);
ImGui::Checkbox(str, &pause_l);
li_hist_pause[i] = pause_l;
sprintf(str, "hold plot##%d", i);
ImGui::Checkbox(str, &hold_l);
li_hist_hold[i] = hold_l;
sprintf(str, "LPF BW##%d", i);
float lpf_bandwidth_l = lpf_bandwidth[i];
ImGui::SliderFloat(str, &lpf_bandwidth_l, 0.5f, 200.0f);
@ -378,8 +403,8 @@ int main(int argc, char* argv[])
ImGui::PlotLines(str, li_hist_mag[i], HIST_DEPTH, 0, 0, -0.0f, 0.1f*plot_scale[i], ImVec2(0.0f, 200.0f));
sprintf(str, "phase##%d", i);
ImGui::PlotLines(str, li_hist_phase[i], HIST_DEPTH, 0, 0, -M_PI, M_PI, ImVec2(0.0f, 200.0f));
ImGui::Text("values: %8.5f %8.5f rad", li_hist_mag[i][511], li_hist_phase[i][511]);
}
ImGui::Text("values: %8.5f %8.5f rad", (double)li_mag[i], (double)li_phase[i]);
}
}