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] =?UTF-8?q?=E2=9C=A8=20added=20interpolations=20for=20wave?= =?UTF-8?q?table=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 87f5ad38..d3e5327c 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();