Compare commits
4 Commits
dcb579fa3f
...
d54e816ff4
Author | SHA1 | Date | |
---|---|---|---|
d54e816ff4 | |||
ad8ae87ac8 | |||
f28f32de4f | |||
944799ec1d |
22
dsp_lib.h
22
dsp_lib.h
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
49
sndlock.cpp
49
sndlock.cpp
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user