Add oversampling

This commit is contained in:
Jean Pierre Cimalando 2020-03-06 11:55:52 +01:00 committed by Paul Fd
parent aa9a5d26f4
commit 26ba7f33b0
7 changed files with 129 additions and 12 deletions

View file

@ -26,6 +26,10 @@ tresult PLUGIN_API SfizzVstControllerNoUi::initialize(FUnknown* context)
kParamNumVoicesRange.createParameter( kParamNumVoicesRange.createParameter(
Steinberg::String("Polyphony"), pid++, nullptr, Steinberg::String("Polyphony"), pid++, nullptr,
0, Vst::ParameterInfo::kNoFlags, Vst::kRootUnitId)); 0, Vst::ParameterInfo::kNoFlags, Vst::kRootUnitId));
parameters.addParameter(
kParamOversamplingRange.createParameter(
Steinberg::String("Oversampling"), pid++, nullptr,
0, Vst::ParameterInfo::kNoFlags, Vst::kRootUnitId));
// MIDI controllers // MIDI controllers
for (unsigned i = 0; i < kNumControllerParams; ++i) { for (unsigned i = 0; i < kNumControllerParams; ++i) {
@ -71,6 +75,40 @@ tresult PLUGIN_API SfizzVstControllerNoUi::getMidiControllerAssignment(int32 bus
} }
} }
tresult PLUGIN_API SfizzVstControllerNoUi::getParamStringByValue(Vst::ParamID tag, Vst::ParamValue valueNormalized, Vst::String128 string)
{
switch (tag) {
case kPidOversampling:
{
int factor = SfizzMisc::adaptOversamplingFactor(
kParamOversamplingRange.denormalize(valueNormalized));
Steinberg::String buf;
buf.printf("%dX", factor);
buf.copyTo(string);
return kResultTrue;
}
}
return EditController::getParamStringByValue(tag, valueNormalized, string);
}
tresult PLUGIN_API SfizzVstControllerNoUi::getParamValueByString(Vst::ParamID tag, Vst::TChar* string, Vst::ParamValue& valueNormalized)
{
switch (tag) {
case kPidOversampling:
{
int factor;
if (!Steinberg::String::scanInt32(string, factor, false))
factor = 1;
valueNormalized = kParamOversamplingRange.normalize(
SfizzMisc::adaptOversamplingFactor(factor));
return kResultTrue;
}
}
return EditController::getParamValueByString(tag, string, valueNormalized);
}
// --- Controller with UI --- // // --- Controller with UI --- //
IPlugView* PLUGIN_API SfizzVstController::createView(FIDString _name) IPlugView* PLUGIN_API SfizzVstController::createView(FIDString _name)
@ -104,6 +142,11 @@ tresult PLUGIN_API SfizzVstController::setParamNormalized(Vst::ParamID tag, Vst:
value = kParamNumVoicesRange.denormalize(normValue); value = kParamNumVoicesRange.denormalize(normValue);
break; break;
} }
case kPidOversampling: {
slotI32 = &_state.oversampling;
value = kParamOversamplingRange.denormalize(normValue);
break;
}
} }
bool update = false; bool update = false;
@ -158,6 +201,7 @@ tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
setParamNormalized(kPidVolume, kParamVolumeRange.normalize(s.volume)); setParamNormalized(kPidVolume, kParamVolumeRange.normalize(s.volume));
setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices)); setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices));
setParamNormalized(kPidOversampling, kParamOversamplingRange.normalize(s.oversampling));
for (StateListener* listener : _stateListeners) for (StateListener* listener : _stateListeners)
listener->onStateChanged(); listener->onStateChanged();

View file

@ -24,6 +24,10 @@ public:
tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, Vst::CtrlNumber midiControllerNumber, Vst::ParamID& id) override; tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, Vst::CtrlNumber midiControllerNumber, Vst::ParamID& id) override;
tresult PLUGIN_API getParamStringByValue(Vst::ParamID tag, Vst::ParamValue valueNormalized, Vst::String128 string) override;
tresult PLUGIN_API getParamValueByString(Vst::ParamID tag, Vst::TChar* string, Vst::ParamValue& valueNormalized) override;
// interfaces // interfaces
OBJ_METHODS(SfizzVstControllerNoUi, Vst::EditController) OBJ_METHODS(SfizzVstControllerNoUi, Vst::EditController)
DEFINE_INTERFACES DEFINE_INTERFACES

View file

@ -81,6 +81,11 @@ void SfizzVstEditor::valueChanged(CControl* ctl)
controller->performEdit(kPidNumVoices, valueNorm); controller->performEdit(kPidNumVoices, valueNorm);
break; break;
case kTagSetOversampling:
controller->setParamNormalized(kPidOversampling, valueNorm);
controller->performEdit(kPidOversampling, valueNorm);
break;
default: default:
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel) if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel)
setActivePanel(tag - kTagFirstChangePanel); setActivePanel(tag - kTagFirstChangePanel);
@ -96,6 +101,7 @@ void SfizzVstEditor::enterOrLeaveEdit(CControl* ctl, bool enter)
switch (tag) { switch (tag) {
case kTagSetVolume: id = kPidVolume; break; case kTagSetVolume: id = kPidVolume; break;
case kTagSetNumVoices: id = kPidNumVoices; break; case kTagSetNumVoices: id = kPidNumVoices; break;
case kTagSetOversampling: id = kPidOversampling; break;
default: return; default: return;
} }
@ -255,17 +261,19 @@ void SfizzVstEditor::createFrameContents()
adjustMinMaxToRangeParam(slider, kPidNumVoices); adjustMinMaxToRangeParam(slider, kPidNumVoices);
_numVoicesSlider = slider; _numVoicesSlider = slider;
// row.top += interRow; row.top += interRow;
// row.bottom += interRow; row.bottom += interRow;
// label = new CTextLabel(leftSide(), "Oversampling"); label = new CTextLabel(leftSide(), "Oversampling");
// label->setFontColor(CColor(0x00, 0x00, 0x00)); label->setFontColor(CColor(0x00, 0x00, 0x00));
// label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
// label->setHoriAlign(kLeftText); label->setHoriAlign(kLeftText);
// panel->addView(label); panel->addView(label);
// slider = new SimpleSlider(rightSide(), this, -1); slider = new SimpleSlider(rightSide(), this, kTagSetOversampling);
// panel->addView(slider); panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidOversampling);
_oversamplingSlider = slider;
// row.top += interRow; // row.top += interRow;
// row.bottom += interRow; // row.bottom += interRow;
@ -276,8 +284,10 @@ void SfizzVstEditor::createFrameContents()
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); // label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
// label->setHoriAlign(kLeftText); // label->setHoriAlign(kLeftText);
// panel->addView(label); // panel->addView(label);
// slider = new SimpleSlider(rightSide(), this, -1); // slider = new SimpleSlider(rightSide(), this, kTag);
// panel->addView(slider); // panel->addView(slider);
// adjustMinMaxToRangeParam(slider, kPid);
// _aSlider = slider;
// row.top += interRow; // row.top += interRow;
// row.bottom += interRow; // row.bottom += interRow;
@ -288,8 +298,10 @@ void SfizzVstEditor::createFrameContents()
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); // label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
// label->setHoriAlign(kLeftText); // label->setHoriAlign(kLeftText);
// panel->addView(label); // panel->addView(label);
// slider = new SimpleSlider(rightSide(), this, -1); // slider = new SimpleSlider(rightSide(), this, kTag);
// panel->addView(slider); // panel->addView(slider);
// adjustMinMaxToRangeParam(slider, kPid);
// _aSlider = slider;
_subPanels[kPanelSettings] = panel; _subPanels[kPanelSettings] = panel;
} }
@ -341,6 +353,8 @@ void SfizzVstEditor::updateStateDisplay()
_volumeSlider->setValue(state.volume); _volumeSlider->setValue(state.volume);
if (_numVoicesSlider) if (_numVoicesSlider)
_numVoicesSlider->setValue(state.numVoices); _numVoicesSlider->setValue(state.numVoices);
if (_oversamplingSlider)
_oversamplingSlider->setValue(state.oversampling);
setActivePanel(uiState.activePanel); setActivePanel(uiState.activePanel);
} }

View file

@ -63,6 +63,7 @@ private:
kTagLoadSfzFile, kTagLoadSfzFile,
kTagSetVolume, kTagSetVolume,
kTagSetNumVoices, kTagSetNumVoices,
kTagSetOversampling,
kTagFirstChangePanel, kTagFirstChangePanel,
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1, kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
}; };
@ -71,4 +72,5 @@ private:
CTextLabel* _fileLabel = nullptr; CTextLabel* _fileLabel = nullptr;
CSliderBase *_volumeSlider = nullptr; CSliderBase *_volumeSlider = nullptr;
CSliderBase *_numVoicesSlider = nullptr; CSliderBase *_numVoicesSlider = nullptr;
CSliderBase *_oversamplingSlider = nullptr;
}; };

View file

@ -81,6 +81,8 @@ void SfizzVstProcessor::syncStateToSynth()
synth->loadSfzFile(_state.sfzFile); synth->loadSfzFile(_state.sfzFile);
synth->setVolume(_state.volume); synth->setVolume(_state.volume);
synth->setNumVoices(_state.numVoices); synth->setNumVoices(_state.numVoices);
synth->setOversamplingFactor(
SfizzMisc::adaptOversamplingFactor(_state.oversampling));
} }
tresult PLUGIN_API SfizzVstProcessor::canProcessSampleSize(int32 symbolicSampleSize) tresult PLUGIN_API SfizzVstProcessor::canProcessSampleSize(int32 symbolicSampleSize)
@ -189,6 +191,21 @@ void SfizzVstProcessor::processParameterChanges(Vst::IParameterChanges& pc)
_semaToWorker.post(); _semaToWorker.post();
} }
break; break;
case kPidOversampling:
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue) {
Vst::IMessage* msg = allocateMessage();
if (!msg)
break;
msg->setMessageID("SetOversampling");
Vst::IAttributeList* attr = msg->getAttributes();
attr->setInt("Oversampling", kParamOversamplingRange.denormalize(value));
if (!_fifoToWorker.push(msg)) {
msg->release();
break;
}
_semaToWorker.post();
}
break;
} }
} }
} }
@ -319,6 +336,14 @@ void SfizzVstProcessor::doBackgroundWork()
_synth->setNumVoices(value); _synth->setNumVoices(value);
} }
} }
else if (!std::strcmp(id, "SetOversampling")) {
int64 value;
if (attr->getInt("Oversampling", value) == kResultTrue) {
_state.oversampling = value;
_synth->setOversamplingFactor(
SfizzMisc::adaptOversamplingFactor(value));
}
}
msg->release(); msg->release();
} }

View file

@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "SfizzVstState.h" #include "SfizzVstState.h"
#include <sfizz.h>
#include <mutex> #include <mutex>
#include <cstring> #include <cstring>
@ -27,6 +28,9 @@ tresult SfizzVstState::load(IBStream* state)
if (!s.readInt32(numVoices)) if (!s.readInt32(numVoices))
return kResultFalse; return kResultFalse;
if (!s.readInt32(oversampling))
return kResultFalse;
return kResultTrue; return kResultTrue;
} }
@ -46,6 +50,9 @@ tresult SfizzVstState::store(IBStream* state) const
if (!s.writeInt32(numVoices)) if (!s.writeInt32(numVoices))
return kResultFalse; return kResultFalse;
if (!s.writeInt32(oversampling))
return kResultFalse;
return kResultTrue; return kResultTrue;
} }
@ -75,3 +82,16 @@ tresult SfizzUiState::store(IBStream* state) const
return kResultTrue; return kResultTrue;
} }
///
int SfizzMisc::adaptOversamplingFactor(int valueDenorm)
{
if (valueDenorm >= 8)
return SFIZZ_OVERSAMPLING_X8;
else if (valueDenorm >= 4)
return SFIZZ_OVERSAMPLING_X4;
else if (valueDenorm >= 2)
return SFIZZ_OVERSAMPLING_X2;
else
return SFIZZ_OVERSAMPLING_X1;
}

View file

@ -20,6 +20,7 @@ enum {
enum { enum {
kPidVolume, kPidVolume,
kPidNumVoices, kPidNumVoices,
kPidOversampling,
kPidMidiCC0, kPidMidiCC0,
kPidMidiCCLast = kPidMidiCC0 + kNumControllerParams - 1, kPidMidiCCLast = kPidMidiCC0 + kNumControllerParams - 1,
kPidMidiAftertouch, kPidMidiAftertouch,
@ -32,6 +33,7 @@ public:
std::string sfzFile; std::string sfzFile;
float volume = 0; float volume = 0;
int numVoices = 64; int numVoices = 64;
int oversampling = 1;
static constexpr uint64 currentStateVersion = 0; static constexpr uint64 currentStateVersion = 0;
@ -75,3 +77,9 @@ struct SfizzParameterRange {
static constexpr SfizzParameterRange kParamVolumeRange(0.0, -60.0, +6.0); static constexpr SfizzParameterRange kParamVolumeRange(0.0, -60.0, +6.0);
static constexpr SfizzParameterRange kParamNumVoicesRange(64.0, 1.0, 256.0); static constexpr SfizzParameterRange kParamNumVoicesRange(64.0, 1.0, 256.0);
static constexpr SfizzParameterRange kParamOversamplingRange(1.0, 1.0, 8.0);
class SfizzMisc {
public:
static int adaptOversamplingFactor(int factor);
};