Skip to content
Open
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
9 changes: 9 additions & 0 deletions core/src/core/api_panning_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ IPLAudioEffectState CPanningEffect::apply(IPLPanningEffectParams* params,
return static_cast<IPLAudioEffectState>(_effect->apply(_params, _in, _out));
}

void CPanningEffect::setSmoothedPanning(bool smoothed)
{
const auto _effect = mHandle.get();
if (!_effect)
return;

_effect->setSmoothedPanning(smoothed);
}

IPLint32 CPanningEffect::getTailSize()
{
auto _effect = mHandle.get();
Expand Down
2 changes: 2 additions & 0 deletions core/src/core/api_panning_effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class CPanningEffect : public IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) override;

virtual void setSmoothedPanning(bool smoothed) override;

virtual IPLint32 getTailSize() override;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) override;
Expand Down
5 changes: 5 additions & 0 deletions core/src/core/api_validation_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,11 @@ class CValidatedPanningEffect : public CPanningEffect

return result;
}

virtual void setSmoothedPanning(bool smoothed) override
{
CPanningEffect::setSmoothedPanning(smoothed);
}
};


Expand Down
41 changes: 30 additions & 11 deletions core/src/core/panning_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ PanningEffect::PanningEffect(const PanningEffectSettings& settings)
void PanningEffect::reset()
{
mPrevDirection = Vector3f::kZero;
mCrossfadeCoefficients = true;
}

AudioEffectState PanningEffect::apply(const PanningEffectParams& params,
Expand All @@ -47,6 +48,11 @@ AudioEffectState PanningEffect::apply(const PanningEffectParams& params,
assert(in.numSamples() == out.numSamples());
assert(in.numChannels() == 1);
assert(out.numChannels() == mSpeakerLayout.numSpeakers);
assert(params.direction != nullptr);

const Vector3f& direction = *params.direction;
if (!mCrossfadeCoefficients)
mPrevDirection = direction;

PanningData panningData{};
PanningData prevPanningData{};
Expand All @@ -57,27 +63,40 @@ AudioEffectState PanningEffect::apply(const PanningEffectParams& params,
// We will be using pairwise constant-power panning for this speaker layout,
// so precalculate some intermediate data instead of recalculating this
// information once for each output channel.
calcPairwisePanningData(*params.direction, mSpeakerLayout, panningData);
calcPairwisePanningData(mPrevDirection, mSpeakerLayout, prevPanningData);
calcPairwisePanningData(direction, mSpeakerLayout, panningData);
if (direction != mPrevDirection)
calcPairwisePanningData(mPrevDirection, mSpeakerLayout, prevPanningData);
else
prevPanningData = panningData;
}

for (auto i = 0; i < out.numChannels(); ++i)
{
auto weight = panningWeight(*params.direction, mSpeakerLayout, i, &panningData);
auto weight = panningWeight(direction, mSpeakerLayout, i, &panningData);
auto weightPrev = panningWeight(mPrevDirection, mSpeakerLayout, i, &prevPanningData);

for (auto j = 0; j < in.numSamples(); ++j)
if (weight == weightPrev)
{
// Crossfade between the panning coefficients for the previous frame and the
// current frame.
auto alpha = static_cast<float>(i) / static_cast<float>(in.numSamples());
auto blendedWeight = alpha * weight + (1.0f - alpha) * weightPrev;

out[i][j] = blendedWeight * in[0][j];
for (auto j = 0; j < in.numSamples(); ++j)
{
out[i][j] = weight * in[0][j];
}
}
else
{
for (auto j = 0; j < in.numSamples(); ++j)
{
// Crossfade between the panning coefficients for the previous frame and the
// current frame.
auto alpha = static_cast<float>(i) / static_cast<float>(in.numSamples());
auto blendedWeight = alpha * weight + (1.0f - alpha) * weightPrev;

out[i][j] = blendedWeight * in[0][j];
}
}
}

mPrevDirection = *params.direction;
mPrevDirection = direction;

return AudioEffectState::TailComplete;
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/core/panning_effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ class PanningEffect
int index,
const PanningData* panningData = nullptr);

void setSmoothedPanning(const bool crossfadeCoefficients) { mCrossfadeCoefficients = crossfadeCoefficients; }

private:
SpeakerLayout mSpeakerLayout;
Vector3f mPrevDirection;
bool mCrossfadeCoefficients;

static float stereoPanningWeight(const Vector3f& direction,
int index);
Expand Down
10 changes: 10 additions & 0 deletions core/src/core/phonon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,16 @@ IPLAPI void IPLCALL iplPanningEffectReset(IPLPanningEffect effect);
*/
IPLAPI IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect, IPLPanningEffectParams* params, IPLAudioBuffer* in, IPLAudioBuffer* out);

/** Enables or disables smooth crossfading of panning coefficients when the source direction changes.

When enabled (default), the panning effect will smoothly crossfade between the previous and current
direction over a single audio frame. When disabled, the new direction will be applied immediately.

\param effect The panning effect.
\param smoothed Set to true to enable smoothing. Set to false to apply new directions immediately.
*/
IPLAPI void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed);

/** Returns the number of tail samples remaining in a panning effect's internal buffers.

Tail samples are audio samples that should be played even after the input to the effect has stopped
Expand Down
10 changes: 10 additions & 0 deletions core/src/core/phonon_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) = 0;

virtual void setSmoothedPanning(bool smoothed) = 0;

virtual IPLint32 getTailSize() = 0;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) = 0;
Expand Down Expand Up @@ -1313,6 +1315,14 @@ IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect,
return reinterpret_cast<api::IPanningEffect*>(effect)->apply(params, in, out);
}

void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed)
{
if (!effect)
return;

reinterpret_cast<api::IPanningEffect*>(effect)->setSmoothedPanning(smoothed);
}

IPLint32 IPLCALL iplPanningEffectGetTailSize(IPLPanningEffect effect)
{
if (!effect)
Expand Down
10 changes: 10 additions & 0 deletions fmod/include/phonon/phonon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,16 @@ IPLAPI void IPLCALL iplPanningEffectReset(IPLPanningEffect effect);
*/
IPLAPI IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect, IPLPanningEffectParams* params, IPLAudioBuffer* in, IPLAudioBuffer* out);

/** Enables or disables smooth crossfading of panning coefficients when the source direction changes.

When enabled (default), the panning effect will smoothly crossfade between the previous and current
direction over a single audio frame. When disabled, the new direction will be applied immediately.

\param effect The panning effect.
\param smoothed Set to true to enable smoothing. Set to false to apply new directions immediately.
*/
IPLAPI void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed);

/** Returns the number of tail samples remaining in a panning effect's internal buffers.

Tail samples are audio samples that should be played even after the input to the effect has stopped
Expand Down
10 changes: 10 additions & 0 deletions fmod/include/phonon/phonon_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) = 0;

virtual void setSmoothedPanning(bool smoothed) = 0;

virtual IPLint32 getTailSize() = 0;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) = 0;
Expand Down Expand Up @@ -1313,6 +1315,14 @@ IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect,
return reinterpret_cast<api::IPanningEffect*>(effect)->apply(params, in, out);
}

void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed)
{
if (!effect)
return;

reinterpret_cast<api::IPanningEffect*>(effect)->setSmoothedPanning(smoothed);
}

IPLint32 IPLCALL iplPanningEffectGetTailSize(IPLPanningEffect effect)
{
if (!effect)
Expand Down
7 changes: 7 additions & 0 deletions fmod/src/spatialize_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ struct State
IPLAudioEffectState ambisonicsState;
bool hasTail;
bool shouldProcessTail;
bool previouslyIdle;
};

enum InitFlags
Expand Down Expand Up @@ -471,6 +472,7 @@ void reset(FMOD_DSP_STATE* state)
effect->ambisonicsState = IPL_AUDIOEFFECTSTATE_TAILCOMPLETE;
effect->hasTail = false;
effect->shouldProcessTail = false;
effect->previouslyIdle = true;
}

FMOD_RESULT F_CALL create(FMOD_DSP_STATE* state)
Expand Down Expand Up @@ -1035,6 +1037,9 @@ FMOD_RESULT F_CALL process(FMOD_DSP_STATE* state,

if (operation == FMOD_DSP_PROCESS_QUERY)
{
if (!effect->previouslyIdle && (!inBuffers || (inputsIdle && !effect->hasTail)))
effect->previouslyIdle = true;

if (!initFmodOutBufferFormat(inBuffers, outBuffers, state, effect->outputFormat))
return FMOD_ERR_DSP_DONTPROCESS;

Expand Down Expand Up @@ -1170,7 +1175,9 @@ FMOD_RESULT F_CALL process(FMOD_DSP_STATE* state,
IPLPanningEffectParams panningParams{};
panningParams.direction = direction;

iplPanningEffectSetSmoothed(effect->panningEffect, !effect->previouslyIdle);
effect->panningState = iplPanningEffectApply(effect->panningEffect, &panningParams, &effect->monoBuffer, &effect->outBuffer);
effect->previouslyIdle = false;
}

if (effect->panningState == IPL_AUDIOEFFECTSTATE_TAILREMAINING)
Expand Down
10 changes: 10 additions & 0 deletions unity/include/phonon/phonon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,16 @@ IPLAPI void IPLCALL iplPanningEffectReset(IPLPanningEffect effect);
*/
IPLAPI IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect, IPLPanningEffectParams* params, IPLAudioBuffer* in, IPLAudioBuffer* out);

/** Enables or disables smooth crossfading of panning coefficients when the source direction changes.

When enabled (default), the panning effect will smoothly crossfade between the previous and current
direction over a single audio frame. When disabled, the new direction will be applied immediately.

\param effect The panning effect.
\param smoothed Set to true to enable smoothing. Set to false to apply new directions immediately.
*/
IPLAPI void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed);

/** Returns the number of tail samples remaining in a panning effect's internal buffers.

Tail samples are audio samples that should be played even after the input to the effect has stopped
Expand Down
10 changes: 10 additions & 0 deletions unity/include/phonon/phonon_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) = 0;

virtual void setSmoothedPanning(bool smoothed) = 0;

virtual IPLint32 getTailSize() = 0;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) = 0;
Expand Down Expand Up @@ -1313,6 +1315,14 @@ IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect,
return reinterpret_cast<api::IPanningEffect*>(effect)->apply(params, in, out);
}

void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed)
{
if (!effect)
return;

reinterpret_cast<api::IPanningEffect*>(effect)->setSmoothedPanning(smoothed);
}

IPLint32 IPLCALL iplPanningEffectGetTailSize(IPLPanningEffect effect)
{
if (!effect)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,16 @@ IPLAPI void IPLCALL iplPanningEffectReset(IPLPanningEffect effect);
*/
IPLAPI IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect, IPLPanningEffectParams* params, IPLAudioBuffer* in, IPLAudioBuffer* out);

/** Enables or disables smooth crossfading of panning coefficients when the source direction changes.

When enabled (default), the panning effect will smoothly crossfade between the previous and current
direction over a single audio frame. When disabled, the new direction will be applied immediately.

\param effect The panning effect.
\param smoothed Set to true to enable smoothing. Set to false to apply new directions immediately.
*/
IPLAPI void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed);

/** Returns the number of tail samples remaining in a panning effect's internal buffers.

Tail samples are audio samples that should be played even after the input to the effect has stopped
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) = 0;

virtual void setSmoothedPanning(bool smoothed) = 0;

virtual IPLint32 getTailSize() = 0;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) = 0;
Expand Down Expand Up @@ -1313,6 +1315,14 @@ IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect,
return reinterpret_cast<api::IPanningEffect*>(effect)->apply(params, in, out);
}

void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed)
{
if (!effect)
return;

reinterpret_cast<api::IPanningEffect*>(effect)->setSmoothedPanning(smoothed);
}

IPLint32 IPLCALL iplPanningEffectGetTailSize(IPLPanningEffect effect)
{
if (!effect)
Expand Down
10 changes: 10 additions & 0 deletions wwise/include/phonon/phonon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,16 @@ IPLAPI void IPLCALL iplPanningEffectReset(IPLPanningEffect effect);
*/
IPLAPI IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect, IPLPanningEffectParams* params, IPLAudioBuffer* in, IPLAudioBuffer* out);

/** Enables or disables smooth crossfading of panning coefficients when the source direction changes.

When enabled (default), the panning effect will smoothly crossfade between the previous and current
direction over a single audio frame. When disabled, the new direction will be applied immediately.

\param effect The panning effect.
\param smoothed Set to true to enable smoothing. Set to false to apply new directions immediately.
*/
IPLAPI void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed);

/** Returns the number of tail samples remaining in a panning effect's internal buffers.

Tail samples are audio samples that should be played even after the input to the effect has stopped
Expand Down
10 changes: 10 additions & 0 deletions wwise/include/phonon/phonon_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class IPanningEffect
IPLAudioBuffer* in,
IPLAudioBuffer* out) = 0;

virtual void setSmoothedPanning(bool smoothed) = 0;

virtual IPLint32 getTailSize() = 0;

virtual IPLAudioEffectState getTail(IPLAudioBuffer* out) = 0;
Expand Down Expand Up @@ -1313,6 +1315,14 @@ IPLAudioEffectState IPLCALL iplPanningEffectApply(IPLPanningEffect effect,
return reinterpret_cast<api::IPanningEffect*>(effect)->apply(params, in, out);
}

void IPLCALL iplPanningEffectSetSmoothed(IPLPanningEffect effect, bool smoothed)
{
if (!effect)
return;

reinterpret_cast<api::IPanningEffect*>(effect)->setSmoothedPanning(smoothed);
}

IPLint32 IPLCALL iplPanningEffectGetTailSize(IPLPanningEffect effect)
{
if (!effect)
Expand Down