116inline double applyExponential(
const float fExponent,
const float fXOffset,
const float fYOffset,
118 float * __restrict__ pA,
float * __restrict__ pB,
119 float fQ,
int nFrames,
int nFramesTotal,
float fStep,
120 float * __restrict__ pfADSRVal ) {
123 float fVal = *pfADSRVal;
125 float fFactor = pow( fExponent, (
double)fStep / nFramesTotal );
128 float fFactor4 = fFactor * fFactor * fFactor * fFactor;
133 for (; i < nFrames - 4; i += 4) {
134 float fVal0 = ( fQ0 - fXOffset ) * fScale + fYOffset,
135 fVal1 = ( fQ1 - fXOffset ) * fScale + fYOffset,
136 fVal2 = ( fQ2 - fXOffset ) * fScale + fYOffset,
137 fVal3 = ( fQ3 - fXOffset ) * fScale + fYOffset;
159 for (; i < nFrames; i++) {
160 fVal = ( fQ - fXOffset ) * fScale + fYOffset;
175bool ADSR::applyADSR(
float *pLeft,
float *pRight,
int nFinalBufferPos,
int nReleaseFrame,
float fStep )
187 int nAttackFrames = std::min( nFinalBufferPos, nReleaseFrame );
188 if ( nAttackFrames * fStep >
m_nAttack ) {
190 nAttackFrames = ceil(
m_nAttack / fStep );
197 nBufferPos += nAttackFrames;
209 int nDecayFrames = std::min( nFinalBufferPos, nReleaseFrame ) - nBufferPos;
210 if ( nDecayFrames * fStep >
m_nDecay ) {
211 nDecayFrames = ceil(
m_nDecay / fStep );
217 nBufferPos += nDecayFrames;
228 int nSustainFrames = std::min( nFinalBufferPos, nReleaseFrame ) - nBufferPos;
229 if ( nSustainFrames != 0 ) {
232 for (
int i = 0; i < nSustainFrames; i++ ) {
237 nBufferPos += nSustainFrames;
250 int nReleaseFrames = nFinalBufferPos - nBufferPos;
258 nBufferPos += nReleaseFrames;
267 for ( ; nBufferPos < nFinalBufferPos; nBufferPos++ ) {
268 pLeft[ nBufferPos ] = pRight[ nBufferPos ] = 0.0;
301 return std::move(
"Attack" );
303 return std::move(
"Decay" );
305 return std::move(
"Sustain" );
307 return std::move(
"Release" );
309 return std::move(
"Idle" );
312 return std::move(
"Attack" );
319 sOutput = QString(
"%1[ADSR]\n" ).arg( sPrefix )
320 .append( QString(
"%1%2attack: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_nAttack ) )
321 .append( QString(
"%1%2decay: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_nDecay ) )
322 .append( QString(
"%1%2sustain: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_fSustain ) )
323 .append( QString(
"%1%2release: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_nRelease ) )
324 .append( QString(
"%1%2state: %3\n" ).arg( sPrefix ).arg( s )
326 .append( QString(
"%1%2ticks: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_fFramesInState ) )
327 .append( QString(
"%1%2value: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_fValue ) )
328 .append( QString(
"%1%2release_value: %3\n" ).arg( sPrefix ).arg( s ).arg(
m_fReleaseValue ) );
330 sOutput = QString(
"[ADSR]" )
331 .append( QString(
" attack: %1" ).arg(
m_nAttack ) )
332 .append( QString(
", decay: %1" ).arg(
m_nDecay ) )
333 .append( QString(
", sustain: %1" ).arg(
m_fSustain ) )
334 .append( QString(
", release: %1" ).arg(
m_nRelease ) )
337 .append( QString(
", value: %1" ).arg(
m_fValue ) )
void attack()
Sets m_state to State::Attack.
static QString StateToQString(State state)
ADSR(unsigned int attack=0, unsigned int decay=0, float sustain=1.0, unsigned int release=1000)
constructor
float m_fValue
current value
float release()
Sets m_state to State::Release and return the current m_fReleaseValue.
unsigned int m_nDecay
Decay phase duration in frames.
unsigned int m_nAttack
Attack phase duration in frames.
double m_fQ
exponential decay state
float m_fSustain
Sustain level.
State m_state
current state
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
bool applyADSR(float *pLeft, float *pRight, int nFinalBufferPos, int nReleaseFrame, float fStep)
Compute and apply successive ADSR values to stereo buffers.
unsigned int m_nRelease
Release phase duration in frames.
float m_fReleaseValue
value when the release state was entered
float m_fFramesInState
Tracks the number of frames passed in the current m_state.
static QString sPrintIndention
String used to format the debugging string output of some core classes.
const float fDecayExponent
const float fAttackExponent
double applyExponential(const float fExponent, const float fXOffset, const float fYOffset, const float fScale, float *__restrict__ pA, float *__restrict__ pB, float fQ, int nFrames, int nFramesTotal, float fStep, float *__restrict__ pfADSRVal)
Apply an exponential envelope to a stereo pair of sample fragments.
const float fDecayYOffset