Add stretch tuning API and implement

This commit is contained in:
Jean Pierre Cimalando 2020-06-11 22:22:47 +02:00
parent 6b906192de
commit 1ba7e6deb2
8 changed files with 52 additions and 0 deletions

View file

@ -137,6 +137,15 @@ SFIZZ_EXPORTED_API void sfizz_set_tuning_frequency(sfizz_synth_t* synth, float f
*/
SFIZZ_EXPORTED_API float sfizz_get_tuning_frequency(sfizz_synth_t* synth);
/**
* @brief Configure stretch tuning using a predefined parametric Railsback curve.
* A ratio 1/2 is supposed to match the average piano; 0 disables (the default).
*
* @param synth The sfizz synth.
* @param ratio The parameter in domain 0-1.
*/
SFIZZ_EXPORTED_API void sfizz_load_stretch_tuning_by_ratio(sfizz_synth_t* synth, float ratio);
/**
* @brief Return the number of regions in the currently loaded SFZ file.
*

View file

@ -119,6 +119,14 @@ public:
*/
float getTuningFrequency() const;
/**
* @brief Configure stretch tuning using a predefined parametric Railsback curve.
* A ratio 1/2 is supposed to match the average piano; 0 disables (the default).
*
* @param ratio The parameter in domain 0-1.
*/
void loadStretchTuningByRatio(float ratio);
/**
* @brief Return the current number of regions loaded.
*/

View file

@ -13,6 +13,7 @@
#include "Wavetables.h"
#include "Curve.h"
#include "Tuning.h"
#include "absl/types/optional.h"
namespace sfz
{
@ -29,6 +30,7 @@ struct Resources
EQPool eqPool { midiState };
WavetablePool wavePool;
Tuning tuning;
absl::optional<StretchTuning> stretch;
void setSampleRate(float samplerate)
{

View file

@ -516,6 +516,17 @@ float sfz::Synth::getTuningFrequency() const
return resources.tuning.getTuningFrequency();
}
void sfz::Synth::loadStretchTuningByRatio(float ratio)
{
CHECK(ratio >= 0.0f && ratio <= 1.0f);
ratio = clamp(ratio, 0.0f, 1.0f);
if (ratio > 0.0f)
resources.stretch = StretchTuning::createRailsbackFromRatio(ratio);
else
resources.stretch.reset();
}
sfz::Voice* sfz::Synth::findFreeVoice() noexcept
{
auto freeVoice = absl::c_find_if(voices, [](const std::unique_ptr<Voice>& voice) {

View file

@ -150,6 +150,12 @@ public:
* @return The frequency which indicates where standard tuning A4 is (default 440 Hz).
*/
float getTuningFrequency() const;
/**
* @brief Configure stretch tuning using a predefined parametric Railsback curve.
*
* @param ratio The parameter in domain 0-1.
*/
void loadStretchTuningByRatio(float ratio);
/**
* @brief Get the current number of regions loaded
*

View file

@ -87,6 +87,11 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
const float numberRetuned = resources.tuning.getKeyFractional12TET(number);
pitchRatio = region->getBasePitchVariation(numberRetuned, value);
// apply stretch tuning if set
if (resources.stretch)
pitchRatio *= resources.stretch->getRatioForFractionalKey(numberRetuned);
baseVolumedB = region->getBaseVolumedB(number);
baseGain = region->getBaseGain();
if (triggerType != TriggerType::CC)

View file

@ -58,6 +58,11 @@ float sfz::Sfizz::getTuningFrequency() const
return synth->getTuningFrequency();
}
void sfz::Sfizz::loadStretchTuningByRatio(float ratio)
{
return synth->loadStretchTuningByRatio(ratio);
}
int sfz::Sfizz::getNumRegions() const noexcept
{
return synth->getNumRegions();

View file

@ -67,6 +67,12 @@ float sfizz_get_tuning_frequency(sfizz_synth_t* synth)
return self->getTuningFrequency();
}
void sfizz_load_stretch_tuning_by_ratio(sfizz_synth_t* synth, float ratio)
{
auto self = reinterpret_cast<sfz::Synth*>(synth);
self->loadStretchTuningByRatio(ratio);
}
void sfizz_free(sfizz_synth_t* synth)
{
delete reinterpret_cast<sfz::Synth*>(synth);