Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions src/effects/native/autopaneffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ EffectManifest AutoPanEffect::getManifest() {
period->setId("period");
period->setName(QObject::tr("Period"));
period->setDescription(QObject::tr("How fast the sound goes from a side to another\n"
"1/4 - 4 beats rounded to 1/2 beat if sync parameter is enabled and tempo is detected (decks and samplers)\n"
"1/4 - 4 seconds if sync parameter disabled or no tempo is detected (mic & aux inputs, master mix)"));
"1/4 - 4 beats rounded to 1/2 beat if tempo is detected (decks and samplers)\n"
"1/4 - 4 seconds if tempo is detected (mic & aux inputs, master mix)"));
period->setControlHint(EffectManifestParameter::ControlHint::KNOB_LINEAR);
period->setSemanticHint(EffectManifestParameter::SemanticHint::UNKNOWN);
period->setUnitsHint(EffectManifestParameter::UnitsHint::UNKNOWN);
period->setDefaultLinkType(EffectManifestParameter::LinkType::LINKED);
period->setDefaultLinkInversion(EffectManifestParameter::LinkInversion::INVERTED);
period->setMinimum(0.0);
period->setMaximum(4.0);
period->setDefault(0.5);
period->setDefault(2.0);

EffectManifestParameter* smoothing = manifest.addParameter();
smoothing->setId("smoothing");
Expand Down Expand Up @@ -99,32 +99,34 @@ void AutoPanEffect::processChannel(const ChannelHandle& handle, AutoPanGroupStat
AutoPanGroupState& gs = *pGroupState;
double width = m_pWidthParameter->value();
double period = m_pPeriodParameter->value();
double smoothing = 0.5-m_pSmoothingParameter->value();
double smoothing = 0.5 - m_pSmoothingParameter->value();

if (groupFeatures.has_beat_length_sec) {
// period is a number of beats
double beats = std::max(roundToFraction(period, 2), 0.25);
// NOTE: Assuming engine is working in stereo.
period = beats * groupFeatures.beat_length_sec * sampleRate * 2;
period = beats * groupFeatures.beat_length_sec * sampleRate;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hear that this cycles the sound around the stereo field in the correct amount of time, but I do not understand why it was wrong to multiply by the channel count.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stereo assumption is already handled in the loop below i += 2


// TODO(xxx) sync phase
//if (groupFeatures.has_beat_fraction) {

} else {
// period is a number of seconds
// NOTE: Assuming engine is working in stereo.
period = std::max(period, 0.25) * sampleRate * 2;
period = std::max(period, 0.25) * sampleRate;
}

// When the period is changed, the position of the sound shouldn't
// so time need to be recalculated
if (gs.m_dPreviousPeriod != -1.0) {
gs.time *= period / gs.m_dPreviousPeriod;
}
gs.m_dPreviousPeriod = period;


if (gs.time > period || enableState == EffectProcessor::ENABLING) {
gs.m_dPreviousPeriod = period;

if (gs.time >= period || enableState == EffectProcessor::ENABLING) {
gs.time = 0;
}


// Normally, the position goes from 0 to 1 linearly. Here we make steps at
// 0.25 and 0.75 to have the sound fully on the right or fully on the left.
// At the end, the "position" value can describe a sinusoid or a square
Expand All @@ -142,6 +144,7 @@ void AutoPanEffect::processChannel(const ChannelHandle& handle, AutoPanGroupStat

double sinusoid = 0;

// NOTE: Assuming engine is working in stereo.
for (unsigned int i = 0; i + 1 < numSamples; i += 2) {

CSAMPLE periodFraction = CSAMPLE(gs.time) / period;
Expand Down Expand Up @@ -180,10 +183,14 @@ void AutoPanEffect::processChannel(const ChannelHandle& handle, AutoPanGroupStat
pOutput[i] *= gs.frac * lawCoef;
pOutput[i+1] *= (1.0f - gs.frac) * lawCoef;

// The time shouldn't be paused if the position does not have its
// expected value due to ramping
if (enableState != EffectProcessor::ENABLING || gs.frac.ramped) {
gs.time++;
gs.time++;
while (gs.time >= period) {
// Click for debug
//pOutput[i] = 1.0f;
//pOutput[i+1] = 1.0f;

// The while loop is required in case period changes the value
gs.time -= period;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/util/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ inline int roundUpToPowerOf2(int v) {
inline double roundToFraction(double value, int denominator) {
int wholePart = value;
double fractionPart = value - wholePart;
int numerator = std::lround(fractionPart * denominator);
return wholePart + (double) numerator / (double) denominator;
double numerator = std::round(fractionPart * denominator);
return wholePart + numerator / denominator;
}

template <typename T>
Expand Down