From 76bd96706eba8d151b88c36155348a0e73da5a07 Mon Sep 17 00:00:00 2001 From: System64 <42580501+system64MC@users.noreply.github.com> Date: Mon, 3 Oct 2022 19:42:52 +0200 Subject: [PATCH 1/5] Update gui.h --- src/gui/gui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/gui.h b/src/gui/gui.h index 203fd20e8..45c43e56c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1611,6 +1611,7 @@ class FurnaceGUI { // wave generator int waveGenBaseShape; + int waveInterpolation; float waveGenDuty; int waveGenPower; float waveGenInvertPoint; From 46b5e64415496177d6a48b774ce033b71065c2ad Mon Sep 17 00:00:00 2001 From: System64 <42580501+system64MC@users.noreply.github.com> Date: Mon, 3 Oct 2022 19:48:07 +0200 Subject: [PATCH 2/5] =?UTF-8?q?=E2=9C=A8=20added=20interpolations=20for=20?= =?UTF-8?q?wavetable=20resize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gui/waveEdit.cpp | 79 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/src/gui/waveEdit.cpp b/src/gui/waveEdit.cpp index 87f5ad38f..d3e5327cd 100644 --- a/src/gui/waveEdit.cpp +++ b/src/gui/waveEdit.cpp @@ -32,6 +32,13 @@ const char* waveGenBaseShapes[4]={ "Pulse" }; +const char* waveInterpolations[4] = { + "None", + "Linear", + "Cosine", + "Cubic" +}; + const float multFactors[17]={ M_PI, 2*M_PI, @@ -519,17 +526,71 @@ void FurnaceGUI::drawWaveEdit() { if (waveGenScaleX<2) waveGenScaleX=2; if (waveGenScaleX>256) waveGenScaleX=256; } + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderInt("##WGInterpolation", &waveInterpolation, 0, 3, waveInterpolations[waveInterpolation])) { + if (waveInterpolation < 0) waveInterpolation = 0; + if (waveInterpolation > 3) waveInterpolation = 3; + //doGenerateWave(); + } ImGui::TableNextColumn(); if (ImGui::Button("Scale X")) { - if (waveGenScaleX>0 && wave->len!=waveGenScaleX) e->lockEngine([this,wave]() { - int origData[256]; - memcpy(origData,wave->data,wave->len*sizeof(int)); - for (int i=0; idata[i]=origData[i*wave->len/waveGenScaleX]; - } - wave->len=waveGenScaleX; - MARK_MODIFIED; - }); + if (waveGenScaleX > 0 && wave->len != waveGenScaleX) e->lockEngine([this, wave]() { + int origData[256]; + // Copy original wave to temp buffer + assert(wave->len <= 256); + memcpy(origData, wave->data, wave->len * sizeof(int)); + + float t = 0; // Index used into `origData` + + for (int i = 0; i < waveGenScaleX; i++, t += (float)wave->len / waveGenScaleX) { + + switch (waveInterpolation) + { + default: // No interpolation + { + wave->data[i] = origData[i * wave->len / waveGenScaleX]; + break; // No interpolation + } + case 0: + { + wave->data[i] = origData[i * wave->len / waveGenScaleX]; + break; + } + case 1: // Linear + { + int idx = t; // Implicitly floors `t` + int s0 = origData[(idx) % wave->len], s1 = origData[(idx + 1) % wave->len]; + double mu = (t - idx); + wave->data[i] = s0 + mu * s1 - (mu * s0); + break; + } + case 2: // Cosine + { + int idx = t; // Implicitly floors `t` + int s0 = origData[(idx) % wave->len], s1 = origData[(idx + 1) % wave->len]; + double mu = (t - idx); + double muCos = (1 - cos(mu * M_PI)) / 2; + wave->data[i] = s0 + muCos * s1 - (muCos * s0); + break; + } + case 3: // Cubic Spline + { + int idx = t; // Implicitly floors `t` + int s0 = origData[(idx) % wave->len], s1 = origData[(idx + 1) % wave->len], s2 = origData[(idx + 2) % wave->len], s3 = origData[(idx + 3) % wave->len]; + double a0, a1, a2, a3; + double mu = (t - idx); + double mu2 = mu * mu; + a0 = -0.5 * s0 + 1.5 * s1 - 1.5 * s2 + 0.5 * s3; + a1 = s0 - 2.5 * s1 + 2 * s2 - 0.5 * s3; + a2 = -0.5 * s0 + 0.5 * s2; + a3 = s1; + wave->data[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3); + } + } + } + wave->len = waveGenScaleX; + MARK_MODIFIED; + }); } ImGui::TableNextRow(); From 77f66642f4159e35d749d62ea1ecf91d984b9550 Mon Sep 17 00:00:00 2001 From: System64 <42580501+system64MC@users.noreply.github.com> Date: Tue, 4 Oct 2022 11:43:14 +0200 Subject: [PATCH 3/5] Update gui.cpp --- src/gui/gui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 2adbf89b1..cce640e02 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -5598,6 +5598,7 @@ FurnaceGUI::FurnaceGUI(): #endif hasACED(false), waveGenBaseShape(0), + waveInterpolation(0), waveGenDuty(0.5f), waveGenPower(1), waveGenInvertPoint(1.0f), From a51840b801707ebae3fb38a85f81c1dee2e24a62 Mon Sep 17 00:00:00 2001 From: System64 <42580501+system64MC@users.noreply.github.com> Date: Wed, 12 Oct 2022 11:59:04 +0200 Subject: [PATCH 4/5] Fixed assertion crash and fixed a bug with the cubic interpolation. The interpolated waveform will now stay in phase. --- src/gui/waveEdit.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/waveEdit.cpp b/src/gui/waveEdit.cpp index d3e5327cd..6913ae372 100644 --- a/src/gui/waveEdit.cpp +++ b/src/gui/waveEdit.cpp @@ -537,7 +537,12 @@ void FurnaceGUI::drawWaveEdit() { if (waveGenScaleX > 0 && wave->len != waveGenScaleX) e->lockEngine([this, wave]() { int origData[256]; // Copy original wave to temp buffer - assert(wave->len <= 256); + // If longer than 256 samples, return + if (wave->len >= 256) + { + showError("ERROR : Wavetable longer than 256 samples!"); + return; + } memcpy(origData, wave->data, wave->len * sizeof(int)); float t = 0; // Index used into `origData` @@ -576,7 +581,7 @@ void FurnaceGUI::drawWaveEdit() { case 3: // Cubic Spline { int idx = t; // Implicitly floors `t` - int s0 = origData[(idx) % wave->len], s1 = origData[(idx + 1) % wave->len], s2 = origData[(idx + 2) % wave->len], s3 = origData[(idx + 3) % wave->len]; + int s0 = origData[((idx - 1 % wave->len + wave->len) % wave->len)], s1 = origData[(idx) % wave->len], s2 = origData[(idx + 1) % wave->len], s3 = origData[(idx + 2) % wave->len]; double a0, a1, a2, a3; double mu = (t - idx); double mu2 = mu * mu; From 0782e3af1de42293ebf2a91b32ea0304bc90f72a Mon Sep 17 00:00:00 2001 From: System64 <42580501+system64MC@users.noreply.github.com> Date: Wed, 12 Oct 2022 12:07:19 +0200 Subject: [PATCH 5/5] Update waveEdit.cpp --- src/gui/waveEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/waveEdit.cpp b/src/gui/waveEdit.cpp index 6913ae372..524fdb402 100644 --- a/src/gui/waveEdit.cpp +++ b/src/gui/waveEdit.cpp @@ -538,7 +538,7 @@ void FurnaceGUI::drawWaveEdit() { int origData[256]; // Copy original wave to temp buffer // If longer than 256 samples, return - if (wave->len >= 256) + if (wave->len > 256) { showError("ERROR : Wavetable longer than 256 samples!"); return;