GUI: wave generator, part 2
This commit is contained in:
parent
7d5f5a91c6
commit
693d457fff
|
@ -4718,9 +4718,9 @@ FurnaceGUI::FurnaceGUI():
|
||||||
#endif
|
#endif
|
||||||
hasACED(false),
|
hasACED(false),
|
||||||
waveGenBaseShape(0),
|
waveGenBaseShape(0),
|
||||||
waveGenDuty(0.0f),
|
waveGenDuty(0.5f),
|
||||||
waveGenPower(0.0f),
|
waveGenPower(1),
|
||||||
waveGenInvertPoint(0.0f),
|
waveGenInvertPoint(1.0f),
|
||||||
waveGenFM(false) {
|
waveGenFM(false) {
|
||||||
// value keys
|
// value keys
|
||||||
valueKeys[SDLK_0]=0;
|
valueKeys[SDLK_0]=0;
|
||||||
|
|
|
@ -1468,7 +1468,9 @@ class FurnaceGUI {
|
||||||
|
|
||||||
// wave generator
|
// wave generator
|
||||||
int waveGenBaseShape;
|
int waveGenBaseShape;
|
||||||
float waveGenDuty, waveGenPower, waveGenInvertPoint;
|
float waveGenDuty;
|
||||||
|
int waveGenPower;
|
||||||
|
float waveGenInvertPoint;
|
||||||
float waveGenAmp[16];
|
float waveGenAmp[16];
|
||||||
float waveGenPhase[16];
|
float waveGenPhase[16];
|
||||||
float waveGenTL[4];
|
float waveGenTL[4];
|
||||||
|
|
|
@ -39,34 +39,67 @@ void FurnaceGUI::doGenerateWave() {
|
||||||
DivWavetable* wave=e->song.wave[curWave];
|
DivWavetable* wave=e->song.wave[curWave];
|
||||||
memset(finalResult,0,sizeof(float)*256);
|
memset(finalResult,0,sizeof(float)*256);
|
||||||
|
|
||||||
|
if (wave->len<2) return;
|
||||||
|
|
||||||
if (waveGenFM) {
|
if (waveGenFM) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch (waveGenBaseShape) {
|
switch (waveGenBaseShape) {
|
||||||
case 0: // sine
|
case 0: // sine
|
||||||
for (int i=0; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
finalResult[i]=0.5*(1.0+sin(i*2.0*M_PI/(double)wave->len));
|
for (int j=0; j<16; j++) {
|
||||||
|
float pos=fmod((waveGenPhase[j]*wave->len)+(i*(j+1)),wave->len);
|
||||||
|
float partial=sin((0.5+pos)*2.0*M_PI/(double)wave->len);
|
||||||
|
partial=pow(partial,waveGenPower);
|
||||||
|
partial*=waveGenAmp[j];
|
||||||
|
finalResult[i]+=partial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // triangle
|
case 1: // triangle
|
||||||
for (int i=0; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
finalResult[i]=2.0*(0.5-fabs(0.5-(i/(double)(wave->len-1))));
|
for (int j=0; j<16; j++) {
|
||||||
|
float pos=fmod((waveGenPhase[j]*wave->len)+(i*(j+1)),wave->len);
|
||||||
|
float partial=4.0*(0.5-fabs(0.5-(pos/(double)(wave->len-1))))-1.0;
|
||||||
|
partial=pow(partial,waveGenPower);
|
||||||
|
partial*=waveGenAmp[j];
|
||||||
|
finalResult[i]+=partial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // saw
|
case 2: // saw
|
||||||
for (int i=0; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
finalResult[i]=i/(double)(wave->len-1);
|
for (int j=0; j<16; j++) {
|
||||||
|
float pos=fmod((waveGenPhase[j]*wave->len)+(i*(j+1)),wave->len);
|
||||||
|
float partial=((2*pos)/(double)(wave->len-1))-1.0;
|
||||||
|
partial=pow(partial,waveGenPower);
|
||||||
|
partial*=waveGenAmp[j];
|
||||||
|
finalResult[i]+=partial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // pulse
|
case 3: // pulse
|
||||||
for (int i=0; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
finalResult[i]=(i>=(wave->len/2))?1:0;
|
for (int j=0; j<16; j++) {
|
||||||
|
float pos=fmod((waveGenPhase[j]*wave->len)+(i*(j+1)),wave->len);
|
||||||
|
float partial=(pos>=(waveGenDuty*wave->len))?1:-1;
|
||||||
|
partial=pow(partial,waveGenPower);
|
||||||
|
partial*=waveGenAmp[j];
|
||||||
|
finalResult[i]+=partial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i=waveGenInvertPoint*wave->len; i<wave->len; i++) {
|
||||||
|
finalResult[i]=-finalResult[i];
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<wave->len; i++) {
|
for (int i=0; i<wave->len; i++) {
|
||||||
|
finalResult[i]=(1.0+finalResult[i])*0.5;
|
||||||
|
if (finalResult[i]<0.0f) finalResult[i]=0.0f;
|
||||||
|
if (finalResult[i]>1.0f) finalResult[i]=1.0f;
|
||||||
wave->data[i]=round(finalResult[i]*wave->max);
|
wave->data[i]=round(finalResult[i]*wave->max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,6 +235,79 @@ void FurnaceGUI::drawWaveEdit() {
|
||||||
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
if (waveGenBaseShape>3) waveGenBaseShape=3;
|
||||||
doGenerateWave();
|
doGenerateWave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("WGShapeProps",2)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Duty");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("##WGDuty",&waveGenDuty,0.0f,1.0f)) {
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Exponent");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderInt("##WGExp",&waveGenPower,1,8)) {
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("XOR Point");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("##WGXOR",&waveGenInvertPoint,0.0f,1.0f)) {
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::TreeNode("Amplitude/Phase")) {
|
||||||
|
if (ImGui::BeginTable("WGShapeProps",3)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.6f);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.4f);
|
||||||
|
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%d",i+1);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::PushID(140+i);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("##WGAmp",&waveGenAmp[i],-1.0f,1.0f)) {
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||||
|
waveGenAmp[i]=0.0f;
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::PushID(140+i);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("##WGPhase",&waveGenPhase[i],0.0f,1.0f)) {
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
|
||||||
|
waveGenPhase[i]=0.0f;
|
||||||
|
doGenerateWave();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("FM")) {
|
if (ImGui::BeginTabItem("FM")) {
|
||||||
|
|
Loading…
Reference in a new issue