Skip to content

Instantly share code, notes, and snippets.

@Xenakios
Created January 21, 2023 01:45
Show Gist options
  • Select an option

  • Save Xenakios/8568166c1d6ebeba6b7fb77256c2f373 to your computer and use it in GitHub Desktop.

Select an option

Save Xenakios/8568166c1d6ebeba6b7fb77256c2f373 to your computer and use it in GitHub Desktop.
void AdditiveVoice::step()
{
float outputs[2] = {0.0f,0.0f};
#ifdef JUCE_WINDOWSA
// calculate SIMD sines with AVX
for (int i=0;i<m_num_partials;i+=8)
{
alignas(32) v8sf temp = _mm256_loadu_ps(&m_partial_phases[i]);
temp = sin256_ps(temp);
_mm256_storeu_ps(&m_output_samples[i],temp);
}
#else
// calculate SIMD sines with SSE on Mac
for (int i=0;i<m_num_partials;i+=4)
{
alignas(32) __m128 temp = _mm_loadu_ps(&m_partial_phases[i]);
temp = sse_mathfun_sin_ps(temp);
_mm_storeu_ps(&m_output_samples[i],temp);
}
#endif
float lfo0 = m_lfos[0].processSample(0.0f)*0.5f;
float amp_morph = m_morph_smoother.getNextValue()+lfo0*modmatrix[0][0];
amp_morph = juce::jlimit<float>(0.0f,1.0f,amp_morph);
amp_morph = amp_morph * (AdditiveSharedData::maxampframes-1);
int amp_morph_i0 = amp_morph;
int amp_morph_i1 = amp_morph_i0+1;
float amp_morph_frac = amp_morph-amp_morph_i0;
float lfo1 = m_lfos[1].processSample(0.0f)*0.5f;
float pan_morph = m_pan_morph_smoother.getNextValue()+lfo1*modmatrix[1][1];
pan_morph = juce::jlimit<float>(0.0f,1.0f,pan_morph);
pan_morph = pan_morph*(AdditiveSharedData::maxpanframes-1);
int pan_morph_i0 = pan_morph;
int pan_morph_i1 = pan_morph_i0+1;
float pan_morph_frac = pan_morph-pan_morph_i0;
// sum sines and advance phases
// might be possible to do this as SIMD too, but won't bother for now
for (int i=0;i<m_num_partials;++i)
{
// we may have calculated aliasing partials, so avoid summing those, as well as ridiculously low ones
if (m_partial_freqs[i]>=16.0f && m_partial_freqs[i]<20000.0f)
{
float gain0 = m_shared_data->partialsmorphtable[amp_morph_i0][i];
float gain1 = m_shared_data->partialsmorphtable[amp_morph_i1][i];
float interp_gain = gain0+(gain1-gain0)*amp_morph_frac;
m_partial_amplitudes[i] = interp_gain;
float pan0 = m_shared_data->partialspanmorphtable[pan_morph_i0][i];
float pan1 = m_shared_data->partialspanmorphtable[pan_morph_i1][i];
float interp_pan = pan0+(pan1-pan0)*pan_morph_frac;
outputs[0] += m_output_samples[i]*interp_gain*interp_pan;
outputs[1] += m_output_samples[i]*interp_gain*(1.0f-interp_pan);
}
float phase = m_partial_phases[i];
phase += m_partial_phaseincs[i];
if (phase>=mkd::twoPi)
phase -= mkd::twoPi;
m_partial_phases[i] = phase;
}
float envgain = m_adsr.getNextSample();
// might want to visualize velocity too, but let's not, for now
m_adsr_vis_amp = envgain;
//output_frame[0] = output*envgain*m_cur_velo*m_pan;
//output_frame[1] = output*envgain*m_cur_velo*(1.0-m_pan);
output_frame[0] = outputs[0]*envgain*m_cur_velo;
output_frame[1] = outputs[1]*envgain*m_cur_velo;
// deactivate voice when ADSR finished
if (!m_adsr.isActive())
{
m_is_available = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment