79 lines
2.6 KiB
C++
79 lines
2.6 KiB
C++
#include "granularplayer.h"
|
|
|
|
using namespace daisysp;
|
|
|
|
void GranularPlayer::Init(float* sample, int size, float sample_rate)
|
|
{
|
|
/*initialize variables to private members*/
|
|
sample_ = sample;
|
|
size_ = size;
|
|
sample_rate_ = sample_rate;
|
|
/*initialize phasors. phs2_ is initialized with a phase offset of 0.5f to create an overlapping effect*/
|
|
phs_.Init(sample_rate_, 0, 0);
|
|
phsImp_.Init(sample_rate_, 0, 0);
|
|
phs2_.Init(sample_rate_, 0, 0.5f);
|
|
phsImp2_.Init(sample_rate_, 0, 0);
|
|
/*calculate sample frequency*/
|
|
sample_frequency_ = sample_rate_ / size_;
|
|
/*initialize half cosine envelope*/
|
|
for(int i = 0; i < 256; i++)
|
|
{
|
|
cosEnv_[i] = sinf((i / 256.0f) * M_PI);
|
|
}
|
|
}
|
|
|
|
uint32_t GranularPlayer::WrapIdx(uint32_t idx, uint32_t sz)
|
|
{
|
|
/*wraps idx to sz*/
|
|
if(idx > sz)
|
|
{
|
|
idx = idx - sz;
|
|
return idx;
|
|
}
|
|
|
|
return idx;
|
|
}
|
|
|
|
float GranularPlayer::CentsToRatio(float cents)
|
|
{
|
|
/*converts cents to ratio*/
|
|
return powf(2.0f, cents / 1200.0f);
|
|
}
|
|
|
|
|
|
float GranularPlayer::MsToSamps(float ms, float samplerate)
|
|
{
|
|
/*converts milliseconds to number of samples*/
|
|
return (ms * 0.001f) * samplerate;
|
|
}
|
|
|
|
float GranularPlayer::NegativeInvert(Phasor* phs, float frequency)
|
|
{
|
|
/*inverts the phase of the phasor if the frequency is negative, mimicking pure data's phasor~ object*/
|
|
return (frequency > 0) ? phs->Process() : ((phs->Process() * -1) + 1);
|
|
}
|
|
|
|
float GranularPlayer::Process(float speed,
|
|
float transposition,
|
|
float grain_size)
|
|
{
|
|
grain_size_ = grain_size;
|
|
speed_ = speed * sample_frequency_;
|
|
transposition_ = (CentsToRatio(transposition) - speed)
|
|
* (grain_size >= 1 ? 1000 / grain_size_ : 1);
|
|
phs_.SetFreq(fabs((speed_ / 2)));
|
|
phs2_.SetFreq(fabs((speed_ / 2)));
|
|
phsImp_.SetFreq(fabs(transposition_));
|
|
phsImp2_.SetFreq(fabs(transposition_));
|
|
idxSpeed_ = NegativeInvert(&phs_, speed_) * size_;
|
|
idxSpeed2_ = NegativeInvert(&phs2_, speed_) * size_;
|
|
idxTransp_ = (NegativeInvert(&phsImp_, transposition_)
|
|
* MsToSamps(grain_size_, sample_rate_));
|
|
idxTransp2_ = (NegativeInvert(&phsImp2_, transposition_)
|
|
* MsToSamps(grain_size_, sample_rate_));
|
|
idx_ = WrapIdx((uint32_t)(idxSpeed_ + idxTransp_), size_);
|
|
idx2_ = WrapIdx((uint32_t)(idxSpeed2_ + idxTransp2_), size_);
|
|
sig_ = sample_[idx_] * cosEnv_[(uint32_t)(phs_.Process() * 256)];
|
|
sig2_ = sample_[idx2_] * cosEnv_[(uint32_t)(phs2_.Process() * 256)];
|
|
return (sig_ + sig2_) / 2;
|
|
} |