Skip to content

Commit

Permalink
Merge pull request #4901 from davidchocholaty/extend_pitch_shift_effe…
Browse files Browse the repository at this point in the history
…ct_options

PitchShiftEffect: extend effect options
  • Loading branch information
daschuer authored Aug 29, 2022
2 parents 9165b22 + fe7fe7d commit c076a79
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 12 deletions.
82 changes: 71 additions & 11 deletions src/effects/backends/builtin/pitchshifteffect.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
#include "effects/backends/builtin/pitchshifteffect.h"

#include <QString>

#include "util/sample.h"

namespace {
static constexpr SINT kSemitonesPerOctave = 12;

static const QString kPitchParameterId = QStringLiteral("pitch");
static const QString kRangeParameterId = QStringLiteral("range");
static const QString kSemitonesModeParameterId = QStringLiteral("semitonesMode");
static const QString kFormantPreservingParameterId = QStringLiteral("formantPreserving");
} // anonymous namespace

PitchShiftEffect::PitchShiftEffect()
: m_currentFormant(false) {
}

PitchShiftGroupState::PitchShiftGroupState(
const mixxx::EngineParameters& engineParameters)
: EffectState(engineParameters) {
Expand Down Expand Up @@ -46,12 +61,12 @@ EffectManifestPointer PitchShiftEffect::getManifest() {
pManifest->setName(QObject::tr("Pitch Shift"));
pManifest->setShortName(QObject::tr("Pitch Shift"));
pManifest->setAuthor("The Mixxx Team");
pManifest->setVersion("1.0");
pManifest->setVersion("2.0");
pManifest->setDescription(QObject::tr(
"Raises or lowers the original pitch of a sound."));

EffectManifestParameterPointer pitch = pManifest->addParameter();
pitch->setId("pitch");
pitch->setId(kPitchParameterId);
pitch->setName(QObject::tr("Pitch"));
pitch->setShortName(QObject::tr("Pitch"));
pitch->setDescription(QObject::tr(
Expand All @@ -61,12 +76,48 @@ EffectManifestPointer PitchShiftEffect::getManifest() {
pitch->setNeutralPointOnScale(0.0);
pitch->setRange(-1.0, 0.0, 1.0);

EffectManifestParameterPointer range = pManifest->addParameter();
range->setId(kRangeParameterId);
range->setName(QObject::tr("Range"));
range->setShortName(QObject::tr("Range"));
range->setDescription(QObject::tr(
"The range of the Pitch knob (0 - 2 octaves).\n"));
range->setValueScaler(EffectManifestParameter::ValueScaler::Linear);
range->setDefaultLinkType(EffectManifestParameter::LinkType::Linked);
range->setNeutralPointOnScale(1.0);
range->setRange(0.0, 1.0, 2.0);

EffectManifestParameterPointer semitonesMode = pManifest->addParameter();
semitonesMode->setId(kSemitonesModeParameterId);
semitonesMode->setName(QObject::tr("Semitones"));
semitonesMode->setShortName(QObject::tr("Semitones"));
semitonesMode->setDescription(QObject::tr(
"Change the pitch in semitone steps instead of continuously."));
semitonesMode->setValueScaler(EffectManifestParameter::ValueScaler::Toggle);
semitonesMode->setUnitsHint(EffectManifestParameter::UnitsHint::Unknown);
semitonesMode->setRange(0, 1, 1);

EffectManifestParameterPointer formantPreserving = pManifest->addParameter();
formantPreserving->setId(kFormantPreservingParameterId);
formantPreserving->setName(QObject::tr("Formant"));
formantPreserving->setShortName(QObject::tr("Formant"));
formantPreserving->setDescription(QObject::tr(
"Preserve the resonant frequencies (formants) of the human vocal tract "
"and other instruments.\n"
"Hint: compensates \"chipmunk\" or \"growling\" voices"));
formantPreserving->setValueScaler(EffectManifestParameter::ValueScaler::Toggle);
formantPreserving->setUnitsHint(EffectManifestParameter::UnitsHint::Unknown);
formantPreserving->setRange(0, 0, 1);

return pManifest;
}

void PitchShiftEffect::loadEngineEffectParameters(
const QMap<QString, EngineEffectParameterPointer>& parameters) {
m_pPitchParameter = parameters.value("pitch");
m_pPitchParameter = parameters.value(kPitchParameterId);
m_pRangeParameter = parameters.value(kRangeParameterId);
m_pSemitonesModeParameter = parameters.value(kSemitonesModeParameterId);
m_pFormantPreservingParameter = parameters.value(kFormantPreservingParameterId);
}

void PitchShiftEffect::processChannel(
Expand All @@ -79,15 +130,24 @@ void PitchShiftEffect::processChannel(
Q_UNUSED(groupFeatures);
Q_UNUSED(enableState);

const double pitchParameter = m_pPitchParameter->value();
if (const bool formantPreserving = m_pFormantPreservingParameter->toBool();
m_currentFormant != formantPreserving) {
m_currentFormant = formantPreserving;

pState->m_pRubberBand->setFormantOption(m_currentFormant
? RubberBand::RubberBandStretcher::
OptionFormantPreserved
: RubberBand::RubberBandStretcher::
OptionFormantShifted);
}

double pitchParameter = m_pPitchParameter->value() * m_pRangeParameter->value();

if (m_pSemitonesModeParameter->toBool()) {
pitchParameter = roundToFraction(pitchParameter, kSemitonesPerOctave);
}

const double pitch = 1.0 + [=] {
if (pitchParameter < 0.0) {
return pitchParameter / 2.0;
} else {
return pitchParameter;
}
}();
const double pitch = std::pow(2.0, pitchParameter);

pState->m_pRubberBand->setPitchScale(pitch);

Expand Down
7 changes: 6 additions & 1 deletion src/effects/backends/builtin/pitchshifteffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "engine/effects/engineeffectparameter.h"
#include "util/class.h"
#include "util/defs.h"
#include "util/math.h"
#include "util/sample.h"
#include "util/types.h"

Expand All @@ -30,7 +31,7 @@ class PitchShiftGroupState : public EffectState {

class PitchShiftEffect final : public EffectProcessorImpl<PitchShiftGroupState> {
public:
PitchShiftEffect() = default;
PitchShiftEffect();

static QString getId();
static EffectManifestPointer getManifest();
Expand All @@ -51,7 +52,11 @@ class PitchShiftEffect final : public EffectProcessorImpl<PitchShiftGroupState>
return getId();
}

bool m_currentFormant;
EngineEffectParameterPointer m_pPitchParameter;
EngineEffectParameterPointer m_pRangeParameter;
EngineEffectParameterPointer m_pSemitonesModeParameter;
EngineEffectParameterPointer m_pFormantPreservingParameter;

DISALLOW_COPY_AND_ASSIGN(PitchShiftEffect);
};
12 changes: 12 additions & 0 deletions src/util/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,15 @@ requires std::is_floating_point_v<T>
}

#undef CMATH_CONSTEXPR

/// https://en.wikipedia.org/wiki/Sign_function
template<typename T>
requires std::is_arithmetic_v<T>
constexpr T sgn(const T a) {
// silence -Wtype-limits
if constexpr (std::is_unsigned_v<T>) {
return static_cast<T>(a > T(0));
} else {
return static_cast<T>(a > T(0)) - static_cast<T>(a < T(0));
}
}

0 comments on commit c076a79

Please sign in to comment.