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(
Steinberg::String("Polyphony"), pid++, nullptr,
0, Vst::ParameterInfo::kNoFlags, Vst::kRootUnitId));
parameters.addParameter(
kParamOversamplingRange.createParameter(
Steinberg::String("Oversampling"), pid++, nullptr,
0, Vst::ParameterInfo::kNoFlags, Vst::kRootUnitId));
// MIDI controllers
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 --- //
IPlugView* PLUGIN_API SfizzVstController::createView(FIDString _name)
@ -104,6 +142,11 @@ tresult PLUGIN_API SfizzVstController::setParamNormalized(Vst::ParamID tag, Vst:
value = kParamNumVoicesRange.denormalize(normValue);
break;
}
case kPidOversampling: {
slotI32 = &_state.oversampling;
value = kParamOversamplingRange.denormalize(normValue);
break;
}
}
bool update = false;
@ -158,6 +201,7 @@ tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
setParamNormalized(kPidVolume, kParamVolumeRange.normalize(s.volume));
setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices));
setParamNormalized(kPidOversampling, kParamOversamplingRange.normalize(s.oversampling));
for (StateListener* listener : _stateListeners)
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 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
OBJ_METHODS(SfizzVstControllerNoUi, Vst::EditController)
DEFINE_INTERFACES

View file

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

View file

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

View file

@ -81,6 +81,8 @@ void SfizzVstProcessor::syncStateToSynth()
synth->loadSfzFile(_state.sfzFile);
synth->setVolume(_state.volume);
synth->setNumVoices(_state.numVoices);
synth->setOversamplingFactor(
SfizzMisc::adaptOversamplingFactor(_state.oversampling));
}
tresult PLUGIN_API SfizzVstProcessor::canProcessSampleSize(int32 symbolicSampleSize)
@ -189,6 +191,21 @@ void SfizzVstProcessor::processParameterChanges(Vst::IParameterChanges& pc)
_semaToWorker.post();
}
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);
}
}
else if (!std::strcmp(id, "SetOversampling")) {
int64 value;
if (attr->getInt("Oversampling", value) == kResultTrue) {
_state.oversampling = value;
_synth->setOversamplingFactor(
SfizzMisc::adaptOversamplingFactor(value));
}
}
msg->release();
}

View file

@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "SfizzVstState.h"
#include <sfizz.h>
#include <mutex>
#include <cstring>
@ -27,6 +28,9 @@ tresult SfizzVstState::load(IBStream* state)
if (!s.readInt32(numVoices))
return kResultFalse;
if (!s.readInt32(oversampling))
return kResultFalse;
return kResultTrue;
}
@ -46,6 +50,9 @@ tresult SfizzVstState::store(IBStream* state) const
if (!s.writeInt32(numVoices))
return kResultFalse;
if (!s.writeInt32(oversampling))
return kResultFalse;
return kResultTrue;
}
@ -75,3 +82,16 @@ tresult SfizzUiState::store(IBStream* state) const
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 {
kPidVolume,
kPidNumVoices,
kPidOversampling,
kPidMidiCC0,
kPidMidiCCLast = kPidMidiCC0 + kNumControllerParams - 1,
kPidMidiAftertouch,
@ -32,6 +33,7 @@ public:
std::string sfzFile;
float volume = 0;
int numVoices = 64;
int oversampling = 1;
static constexpr uint64 currentStateVersion = 0;
@ -75,3 +77,9 @@ struct SfizzParameterRange {
static constexpr SfizzParameterRange kParamVolumeRange(0.0, -60.0, +6.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);
};