GUI: wave generator, part 1
This commit is contained in:
parent
173e9b0df9
commit
7d5f5a91c6
|
@ -4720,7 +4720,8 @@ FurnaceGUI::FurnaceGUI():
|
||||||
waveGenBaseShape(0),
|
waveGenBaseShape(0),
|
||||||
waveGenDuty(0.0f),
|
waveGenDuty(0.0f),
|
||||||
waveGenPower(0.0f),
|
waveGenPower(0.0f),
|
||||||
waveGenInvertPoint(0.0f) {
|
waveGenInvertPoint(0.0f),
|
||||||
|
waveGenFM(false) {
|
||||||
// value keys
|
// value keys
|
||||||
valueKeys[SDLK_0]=0;
|
valueKeys[SDLK_0]=0;
|
||||||
valueKeys[SDLK_1]=1;
|
valueKeys[SDLK_1]=1;
|
||||||
|
@ -4782,6 +4783,20 @@ FurnaceGUI::FurnaceGUI():
|
||||||
|
|
||||||
memset(acedData,0,23);
|
memset(acedData,0,23);
|
||||||
|
|
||||||
|
memset(waveGenAmp,0,sizeof(float)*16);
|
||||||
|
memset(waveGenPhase,0,sizeof(float)*16);
|
||||||
|
memset(waveGenTL,0,sizeof(float)*4);
|
||||||
|
memset(waveGenMult,0,sizeof(int)*4);
|
||||||
|
memset(waveGenFB,0,sizeof(float)*4);
|
||||||
|
memset(waveGenFMCon1,0,sizeof(bool)*4);
|
||||||
|
memset(waveGenFMCon2,0,sizeof(bool)*3);
|
||||||
|
memset(waveGenFMCon3,0,sizeof(bool)*2);
|
||||||
|
|
||||||
|
waveGenAmp[0]=1.0f;
|
||||||
|
waveGenFMCon1[0]=true;
|
||||||
|
waveGenFMCon2[0]=true;
|
||||||
|
waveGenFMCon3[0]=true;
|
||||||
|
|
||||||
memset(pianoKeyHit,0,sizeof(float)*180);
|
memset(pianoKeyHit,0,sizeof(float)*180);
|
||||||
memset(pianoKeyPressed,0,sizeof(bool)*180);
|
memset(pianoKeyPressed,0,sizeof(bool)*180);
|
||||||
|
|
||||||
|
|
|
@ -1472,10 +1472,12 @@ class FurnaceGUI {
|
||||||
float waveGenAmp[16];
|
float waveGenAmp[16];
|
||||||
float waveGenPhase[16];
|
float waveGenPhase[16];
|
||||||
float waveGenTL[4];
|
float waveGenTL[4];
|
||||||
|
int waveGenMult[4];
|
||||||
float waveGenFB[4];
|
float waveGenFB[4];
|
||||||
bool waveGenFMCon1[4];
|
bool waveGenFMCon1[4];
|
||||||
bool waveGenFMCon2[3];
|
bool waveGenFMCon2[3];
|
||||||
bool waveGenFMCon3[2];
|
bool waveGenFMCon3[2];
|
||||||
|
bool waveGenFM;
|
||||||
|
|
||||||
void drawSSGEnv(unsigned char type, const ImVec2& size);
|
void drawSSGEnv(unsigned char type, const ImVec2& size);
|
||||||
void drawWaveform(unsigned char type, bool opz, const ImVec2& size);
|
void drawWaveform(unsigned char type, bool opz, const ImVec2& size);
|
||||||
|
@ -1600,6 +1602,8 @@ class FurnaceGUI {
|
||||||
void noteInput(int num, int key, int vol=-1);
|
void noteInput(int num, int key, int vol=-1);
|
||||||
void valueInput(int num, bool direct=false, int target=-1);
|
void valueInput(int num, bool direct=false, int target=-1);
|
||||||
|
|
||||||
|
void doGenerateWave();
|
||||||
|
|
||||||
void doUndoSample();
|
void doUndoSample();
|
||||||
void doRedoSample();
|
void doRedoSample();
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,60 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "plot_nolerp.h"
|
#include "plot_nolerp.h"
|
||||||
#include "IconsFontAwesome4.h"
|
#include "IconsFontAwesome4.h"
|
||||||
#include "misc/cpp/imgui_stdlib.h"
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
|
#include <math.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
const char* waveGenBaseShapes[4]={
|
||||||
|
"Sine",
|
||||||
|
"Triangle",
|
||||||
|
"Saw",
|
||||||
|
"Pulse"
|
||||||
|
};
|
||||||
|
|
||||||
|
void FurnaceGUI::doGenerateWave() {
|
||||||
|
float finalResult[256];
|
||||||
|
if (curWave<0 || curWave>=(int)e->song.wave.size()) return;
|
||||||
|
|
||||||
|
DivWavetable* wave=e->song.wave[curWave];
|
||||||
|
memset(finalResult,0,sizeof(float)*256);
|
||||||
|
|
||||||
|
if (waveGenFM) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
switch (waveGenBaseShape) {
|
||||||
|
case 0: // sine
|
||||||
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
finalResult[i]=0.5*(1.0+sin(i*2.0*M_PI/(double)wave->len));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // triangle
|
||||||
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
finalResult[i]=2.0*(0.5-fabs(0.5-(i/(double)(wave->len-1))));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // saw
|
||||||
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
finalResult[i]=i/(double)(wave->len-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // pulse
|
||||||
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
finalResult[i]=(i>=(wave->len/2))?1:0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
wave->data[i]=round(finalResult[i]*wave->max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::drawWaveEdit() {
|
void FurnaceGUI::drawWaveEdit() {
|
||||||
if (nextWindow==GUI_WINDOW_WAVE_EDIT) {
|
if (nextWindow==GUI_WINDOW_WAVE_EDIT) {
|
||||||
waveEditOpen=true;
|
waveEditOpen=true;
|
||||||
|
@ -144,10 +192,21 @@ void FurnaceGUI::drawWaveEdit() {
|
||||||
|
|
||||||
if (ImGui::BeginTabBar("WaveGenOpt")) {
|
if (ImGui::BeginTabBar("WaveGenOpt")) {
|
||||||
if (ImGui::BeginTabItem("Shapes")) {
|
if (ImGui::BeginTabItem("Shapes")) {
|
||||||
ImGui::Button("Square");
|
waveGenFM=false;
|
||||||
|
|
||||||
|
if (waveGenBaseShape<0) waveGenBaseShape=0;
|
||||||
|
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##WGShape",&waveGenBaseShape,0,3,waveGenBaseShapes[waveGenBaseShape])) {
|
||||||
|
if (waveGenBaseShape<0) waveGenBaseShape=0;
|
||||||
|
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("FM")) {
|
if (ImGui::BeginTabItem("FM")) {
|
||||||
|
waveGenFM=true;
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Mangle")) {
|
if (ImGui::BeginTabItem("Mangle")) {
|
||||||
|
|
Loading…
Reference in a new issue