mirror of
https://github.com/ggerganov/ggwave.git
synced 2026-05-10 10:57:39 +08:00
spectrogram : toggle filters
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -42,6 +43,10 @@ int g_binMax = g_nBins;
|
|||||||
|
|
||||||
float g_scale = 30.0;
|
float g_scale = 30.0;
|
||||||
|
|
||||||
|
bool g_filter0 = false;
|
||||||
|
bool g_filter1 = false;
|
||||||
|
bool g_filter2 = false;
|
||||||
|
|
||||||
bool g_showControls = true;
|
bool g_showControls = true;
|
||||||
|
|
||||||
int g_freqDataHead = 0;
|
int g_freqDataHead = 0;
|
||||||
@@ -184,6 +189,10 @@ bool GGWave_mainLoop() {
|
|||||||
static int workI[2*g_nSamplesPerFrame];
|
static int workI[2*g_nSamplesPerFrame];
|
||||||
static float workF[g_nSamplesPerFrame/2];
|
static float workF[g_nSamplesPerFrame/2];
|
||||||
|
|
||||||
|
static float workF0[g_nSamplesPerFrame];
|
||||||
|
static float workF1[g_nSamplesPerFrame];
|
||||||
|
static float workF2[11];
|
||||||
|
|
||||||
if (!isInitialzed) {
|
if (!isInitialzed) {
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
memset(out, 0, sizeof(out));
|
memset(out, 0, sizeof(out));
|
||||||
@@ -191,6 +200,10 @@ bool GGWave_mainLoop() {
|
|||||||
memset(workI, 0, sizeof(workI));
|
memset(workI, 0, sizeof(workI));
|
||||||
memset(workF, 0, sizeof(workF));
|
memset(workF, 0, sizeof(workF));
|
||||||
|
|
||||||
|
memset(workF0, 0, sizeof(workF0));
|
||||||
|
memset(workF1, 0, sizeof(workF1));
|
||||||
|
memset(workF2, 0, sizeof(workF2));
|
||||||
|
|
||||||
isInitialzed = true;
|
isInitialzed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +213,18 @@ bool GGWave_mainLoop() {
|
|||||||
n = SDL_DequeueAudio(g_devIdInp, data, sizeof(float)*g_nSamplesPerFrame);
|
n = SDL_DequeueAudio(g_devIdInp, data, sizeof(float)*g_nSamplesPerFrame);
|
||||||
if (n <= 0) break;
|
if (n <= 0) break;
|
||||||
|
|
||||||
|
if (g_filter2) {
|
||||||
|
GGWave::filter(GGWAVE_FILTER_FIRST_ORDER_HIGH_PASS, data, g_nSamplesPerFrame, 750.0f, GGWave::kDefaultSampleRate, workF2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_filter0) {
|
||||||
|
GGWave::filter(GGWAVE_FILTER_HANN, data, g_nSamplesPerFrame, 750.0f, GGWave::kDefaultSampleRate, workF0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_filter1) {
|
||||||
|
GGWave::filter(GGWAVE_FILTER_HAMMING, data, g_nSamplesPerFrame, 750.0f, GGWave::kDefaultSampleRate, workF1);
|
||||||
|
}
|
||||||
|
|
||||||
if (GGWave::computeFFTR(data, out, g_nSamplesPerFrame, workI, workF) == false) {
|
if (GGWave::computeFFTR(data, out, g_nSamplesPerFrame, workI, workF) == false) {
|
||||||
fprintf(stderr, "Failed to compute FFT!\n");
|
fprintf(stderr, "Failed to compute FFT!\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -505,7 +530,19 @@ int main(int argc, char** argv) {
|
|||||||
auto v = g_freqData[g_binMin + i].mag[k];
|
auto v = g_freqData[g_binMin + i].mag[k];
|
||||||
ImVec4 c = { 0.0f, 1.0f, 0.0, 0.0f };
|
ImVec4 c = { 0.0f, 1.0f, 0.0, 0.0f };
|
||||||
c.w = v/(g_scale*sum);
|
c.w = v/(g_scale*sum);
|
||||||
drawList->AddRectFilled({ p0.x + i*dx, p0.y + j*dy }, { p0.x + i*dx + dx, p0.y + j*dy + dy }, ImGui::ColorConvertFloat4ToU32(c));
|
|
||||||
|
const ImVec2 rp0 = { p0.x + i*dx , p0.y + j*dy };
|
||||||
|
const ImVec2 rp1 = { p0.x + i*dx + dx, p0.y + j*dy + dy };
|
||||||
|
|
||||||
|
drawList->AddRectFilled(rp0, rp1, ImGui::ColorConvertFloat4ToU32(c));
|
||||||
|
|
||||||
|
// if hovering -> tooltip
|
||||||
|
if (ImGui::IsMouseHoveringRect(rp0, rp1)) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("%.2f Hz", g_freqData[g_binMin + i].freq);
|
||||||
|
ImGui::Text("%.2f", v);
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +561,7 @@ int main(int argc, char** argv) {
|
|||||||
if (g_showControls) {
|
if (g_showControls) {
|
||||||
ImGui::SetNextWindowFocus();
|
ImGui::SetNextWindowFocus();
|
||||||
ImGui::SetNextWindowPos({ std::max(20.0f, displaySize.x - 400.0f - 20.0f), 20.0f });
|
ImGui::SetNextWindowPos({ std::max(20.0f, displaySize.x - 400.0f - 20.0f), 20.0f });
|
||||||
ImGui::SetNextWindowSize({ std::min(displaySize.x - 40.0f, 400.0f), 180.0f });
|
ImGui::SetNextWindowSize({ std::min(displaySize.x - 40.0f, 400.0f), 210.0f });
|
||||||
ImGui::Begin("Controls", &g_showControls);
|
ImGui::Begin("Controls", &g_showControls);
|
||||||
ImGui::Text("Press 'c' to hide/show this window");
|
ImGui::Text("Press 'c' to hide/show this window");
|
||||||
{
|
{
|
||||||
@@ -535,6 +572,17 @@ int main(int argc, char** argv) {
|
|||||||
ImGui::DragInt("Max", &g_binMax, 1, g_binMin + 1, g_nBins, buf);
|
ImGui::DragInt("Max", &g_binMax, 1, g_binMin + 1, g_nBins, buf);
|
||||||
}
|
}
|
||||||
ImGui::DragFloat("Scale", &g_scale, 1.0f, 1.0f, 1000.0f);
|
ImGui::DragFloat("Scale", &g_scale, 1.0f, 1.0f, 1000.0f);
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("High-pass", &g_filter2)) {
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Checkbox("Hann", &g_filter0)) {
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Checkbox("Hamming", &g_filter1)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("%s", "");
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (ImGui::SliderFloat("Offset", &g_sampleRateOffset, -2048, 2048)) {
|
if (ImGui::SliderFloat("Offset", &g_sampleRateOffset, -2048, 2048)) {
|
||||||
GGWave_deinit();
|
GGWave_deinit();
|
||||||
|
|||||||
Reference in New Issue
Block a user