Skip to content

Commit

Permalink
Tuning Patches, Status Panel, and Patch Versions (#1038)
Browse files Browse the repository at this point in the history
This commit sets up a display of statuses in the synth so we
can bring to the front thigns like MPE and Tuning and bind the
menus more comprehensively. It also brings to bear the ability
(optionally) to store a tuning in a patch and the correct state
machine for what to do when loading a patch with tuning with
tuning active.

It almost completely addresses the remainder of #828
Addresses the streaming incompatability in #1035

Still outstanding is optionally a "lock" and to apply
the streaming version option to FX (which is #1037)

Handle streaming revision parameter set changes in OSCes. Deals with
  • Loading branch information
baconpaul authored Aug 17, 2019
1 parent f752d12 commit 89d0367
Show file tree
Hide file tree
Showing 14 changed files with 454 additions and 101 deletions.
23 changes: 12 additions & 11 deletions assets/original-vector/SVG/exported/bmp00102.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/original-vector/SVG/master/Surge_OG.sketch
Binary file not shown.
1 change: 1 addition & 0 deletions premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ function plugincommon()
"src/common/gui/CNumberField.cpp",
"src/common/gui/COscillatorDisplay.cpp",
"src/common/gui/CPatchBrowser.cpp",
"src/common/gui/CStatusPanel.cpp",
"src/common/gui/CScalableBitmap.cpp",
"src/common/gui/CSnapshotMenu.cpp",
"src/common/gui/CSurgeSlider.cpp",
Expand Down
28 changes: 27 additions & 1 deletion src/common/SurgePatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ void SurgePatch::update_controls(bool init,
if (t_osc)
{
t_osc->init_ctrltypes();
t_osc->handleStreamingMismatches( streamingRevision, currentSynthStreamingRevision );
if (init || (init_osc == &sc.osc[osc]))
t_osc->init_default_values();
delete t_osc;
Expand Down Expand Up @@ -993,7 +994,9 @@ void SurgePatch::load_xml(const void* data, int datasize, bool is_preset)

int revision = 0;
patch->QueryIntAttribute("revision", &revision);

streamingRevision = revision;
currentSynthStreamingRevision = ff_revision;

TiXmlElement* meta = TINYXML_SAFE_TO_ELEMENT(patch->FirstChild("meta"));
if (meta)
{
Expand Down Expand Up @@ -1355,6 +1358,20 @@ void SurgePatch::load_xml(const void* data, int datasize, bool is_preset)
p = TINYXML_SAFE_TO_ELEMENT(p->NextSibling("entry"));
}

patchTuning.tuningStoredInPatch = false;
TiXmlElement *pt = TINYXML_SAFE_TO_ELEMENT(patch->FirstChild("patchTuning"));
if( pt )
{
const char* td;
if( pt &&
(td = pt->Attribute("v") ))
{
patchTuning.tuningStoredInPatch = true;
auto tc = base64_decode(td);
patchTuning.tuningContents = tc;
}
}

dawExtraState.isPopulated = false;
TiXmlElement *de = TINYXML_SAFE_TO_ELEMENT(patch->FirstChild("dawExtraState"));
if( de )
Expand Down Expand Up @@ -1579,6 +1596,15 @@ unsigned int SurgePatch::save_xml(void** data) // allocates mem, must be freed b
patch.InsertEndChild(mw);
}

if( patchTuning.tuningStoredInPatch )
{
TiXmlElement pt( "patchTuning" );
pt.SetAttribute("v", base64_encode( (unsigned const char *)patchTuning.tuningContents.c_str(),
patchTuning.tuningContents.size() ).c_str() );

patch.InsertEndChild(pt);
}

TiXmlElement dawExtraXML("dawExtraState");
dawExtraXML.SetAttribute( "populated", dawExtraState.isPopulated ? 1 : 0 );

Expand Down
11 changes: 11 additions & 0 deletions src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,13 @@ struct DAWExtraStateStorage
std::string tuningContents = "";
};


struct PatchTuningStorage
{
bool tuningStoredInPatch = false;
std::string tuningContents = "";
};

class SurgeStorage;

class SurgePatch
Expand Down Expand Up @@ -438,6 +445,7 @@ class SurgePatch

StepSequencerStorage stepsequences[2][n_lfos];

PatchTuningStorage patchTuning;
DAWExtraStateStorage dawExtraState;

std::vector<Parameter*> param_ptr;
Expand All @@ -453,6 +461,9 @@ class SurgePatch
std::string name, category, author, comment;
// metaparameters
char CustomControllerLabel[n_customcontrollers][16];

int streamingRevision;
int currentSynthStreamingRevision;
};

struct Patch
Expand Down
19 changes: 19 additions & 0 deletions src/common/SurgeSynthesizerIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@ void SurgeSynthesizer::loadPatch(int id)
loadRaw(data, cs, true);
free(data);

/*
** OK so at this point we may have loaded a patch with a tuning override
*/
if( storage.getPatch().patchTuning.tuningStoredInPatch )
{
if( storage.isStandardTuning )
storage.retuneToScale(Surge::Storage::parseSCLData(storage.getPatch().patchTuning.tuningContents ));
else
{
auto okc = Surge::UserInteractions::promptOKCancel(std::string("The patch you loaded contains a recommended tuning, but you ") +
"already have a tuning in place. Do you want to override your current tuning " +
"with the patch sugeested tuning?",
"Replace Tuning? (The rest of the patch will still load).");
if( okc == Surge::UserInteractions::MessageResult::OK )
storage.retuneToScale(Surge::Storage::parseSCLData(storage.getPatch().patchTuning.tuningContents));
}

}

masterfade = 1.f;
#if AU
/* AUPreset preset;
Expand Down
12 changes: 12 additions & 0 deletions src/common/dsp/Oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,18 @@ float osc_sine::valueFromSinAndCos(float svalue, float cvalue)
return pvalue;
}

void osc_sine::handleStreamingMismatches(int streamingRevision, int currentSynthStreamingRevision)
{
if( streamingRevision <= 10 )
{
oscdata->p[1].val.f = 0;
}
if( streamingRevision <= 9 )
{
oscdata->p[0].val.i = 0;
}
}

void osc_sine::init_ctrltypes()
{
oscdata->p[0].set_name("WaveShape");
Expand Down
6 changes: 6 additions & 0 deletions src/common/dsp/Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class alignas(16) Oscillator
return (float)(M_PI * (16.35159783) * storage->note_to_pitch(x) * dsamplerate_os_inv);
}

virtual void handleStreamingMismatches(int streamingRevision, int currentSynthStreamingRevision)
{
// No-op here.
}

protected:
SurgeStorage* storage;
OscillatorStorage* oscdata;
Expand Down Expand Up @@ -64,6 +69,7 @@ class osc_sine : public Oscillator
float lastvalue = 0;

float valueFromSinAndCos(float svalue, float cvalue);
virtual void handleStreamingMismatches(int s, int synths) override;
};

class FMOscillator : public Oscillator
Expand Down
2 changes: 0 additions & 2 deletions src/common/gui/CPatchBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ extern CFontRef patchNameFont;

void CPatchBrowser::draw(CDrawContext* dc)
{
dc->setFillColor(kBlackCColor);
CRect size = getViewSize();
CRect ar(size);
ar.inset(1, 0);
Expand Down Expand Up @@ -41,7 +40,6 @@ void CPatchBrowser::draw(CDrawContext* dc)
dc->drawString(category.c_str(), al, kLeftText, true);
al.offset(0, 12);
dc->drawString(author.c_str(), al, kLeftText, true);

setDirty(false);
}

Expand Down
2 changes: 2 additions & 0 deletions src/common/gui/CPatchBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
class CPatchBrowser : public VSTGUI::CControl
{
public:

CPatchBrowser(const VSTGUI::CRect& size, VSTGUI::IControlListener* listener, long tag, SurgeStorage* storage)
: VSTGUI::CControl(size, listener, tag, 0)
{
Expand Down Expand Up @@ -52,6 +53,7 @@ class CPatchBrowser : public VSTGUI::CControl
author = "";
setDirty(true);
}

virtual void draw(VSTGUI::CDrawContext* dc);
VSTGUI::CMouseEventResult onMouseDown(VSTGUI::CPoint& where, const VSTGUI::CButtonState& button);
void loadPatch(int id);
Expand Down
94 changes: 94 additions & 0 deletions src/common/gui/CStatusPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "CStatusPanel.h"
#include "RuntimeFont.h"
#include "SurgeGUIEditor.h"

using namespace VSTGUI;

void CStatusPanel::draw( VSTGUI::CDrawContext *dc )
{
auto size = getViewSize();

dc->setFont(displayFont);
auto sw = dc->getStringWidth("Status");
dc->setFontColor(kBlackCColor);
dc->drawString("Status", CPoint( size.left + size.getWidth()/2 - sw/2, size.top + 8 ), true );

std::string labs[numDisplayFeatures];
labs[mpeMode] = "mpe";
labs[tuningMode] = "tun";
int y0 = 13;
int boxSize = 13;
for( int i=0; i<numDisplayFeatures; ++i )
{
int xp = size.left + 2;
int yp = size.top + y0 + i * boxSize;
int w = size.getWidth() - 4;;
int h = boxSize - 2;
if( i == mpeMode )
mpeBox = CRect(xp,yp,xp+w,yp+h);
if( i == tuningMode )
tuningBox = CRect(xp,yp,xp+w,yp+h);

auto hlbg = true;
auto ol = CColor(0x97, 0x97, 0x97 );
auto bg = CColor(0xe3, 0xe3, 0xe3 );
auto fg = kBlackCColor;
auto hl = CColor(0xff, 0x9A, 0x10 );
if( ! dispfeatures[i] )
{
hlbg = false;
}

dc->setFrameColor(bg);;
auto p = dc->createRoundRectGraphicsPath(CRect(xp,yp,xp+w,yp+h), 5 );
dc->setFillColor(bg);;
dc->drawGraphicsPath(p, CDrawContext::kPathFilled);
dc->setFrameColor(ol);
dc->drawGraphicsPath(p, CDrawContext::kPathStroked);
p->forget();

if( hlbg )
{
auto p = dc->createRoundRectGraphicsPath(CRect(xp+2,yp+2,xp+w-2,yp+h-2), 3 );
dc->setFillColor(hl);
dc->drawGraphicsPath(p, CDrawContext::kPathFilled);
p->forget();
}
dc->setFont(displayFont);
auto sw = dc->getStringWidth(labs[i].c_str());
dc->setFontColor(fg);
dc->drawString(labs[i].c_str(), CPoint( xp + w/2 - sw/2, yp + h - 2 ), true );
}
}

VSTGUI::CMouseEventResult CStatusPanel::onMouseDown(VSTGUI::CPoint& where, const VSTGUI::CButtonState& button)
{
if( mpeBox.pointInside(where) && editor )
{
if( button & kLButton )
{
editor->toggleMPE();
}
else if( button & kRButton )
{
editor->showMPEMenu(where);
}
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}

if( tuningBox.pointInside(where) && editor )
{
if( button & kLButton )
{
editor->toggleTuning();
}
else if( button & kRButton )
{
editor->showTuningMenu(where);
}
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}

return CControl::onMouseDown(where, button);
}

53 changes: 53 additions & 0 deletions src/common/gui/CStatusPanel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//-------------------------------------------------------------------------------------------------------
// Copyright 2005 Claes Johanson & Vember Audio
//-------------------------------------------------------------------------------------------------------
#pragma once
#include "SurgeStorage.h"
#include "vstcontrols.h"

class SurgeGUIEditor;

class CStatusPanel : public VSTGUI::CControl
{
public:

typedef enum {
mpeMode,
tuningMode,
numDisplayFeatures
} DisplayFeatures;

CStatusPanel(const VSTGUI::CRect& size, VSTGUI::IControlListener* listener, long tag, SurgeStorage* storage)
: VSTGUI::CControl(size, listener, tag, 0)
{
for( auto i=0; i<numDisplayFeatures; ++i )
dispfeatures[i] = false;

}

void setDisplayFeature( DisplayFeatures df, bool v )
{
if( dispfeatures[df] != v )
{
dispfeatures[df] = v;
invalid();
}
}

void setEditor(SurgeGUIEditor *e)
{
editor = e;
}

virtual void draw(VSTGUI::CDrawContext* dc);
VSTGUI::CMouseEventResult onMouseDown(VSTGUI::CPoint& where, const VSTGUI::CButtonState& button);

protected:
bool dispfeatures[numDisplayFeatures];
SurgeStorage* storage = nullptr;
SurgeGUIEditor *editor = nullptr;
VSTGUI::CRect mpeBox, tuningBox, tuningLock;


CLASS_METHODS(CStatusPanel, VSTGUI::CControl)
};
Loading

0 comments on commit 89d0367

Please sign in to comment.