Added DaisySP
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (c) 2020 Electrosmith, Corp, Vinícius Fernandes
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef DSY_GRANULARPLAYER_H
|
||||
#define DSY_GRANULARPLAYER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include "Control/phasor.h"
|
||||
#ifdef __cplusplus
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
|
||||
namespace daisysp
|
||||
{
|
||||
/** GranularPlayer Module
|
||||
|
||||
Date: November, 2023
|
||||
|
||||
Author: Vinícius Fernandes
|
||||
|
||||
GranularPlayer is a lookup table player that provides independent time stretching and pitch shifting
|
||||
via granulation.
|
||||
Inspired by the grain.player object from else pure data's library.
|
||||
*/
|
||||
|
||||
class GranularPlayer
|
||||
{
|
||||
public:
|
||||
GranularPlayer() {}
|
||||
~GranularPlayer() {}
|
||||
|
||||
/** Initializes the GranularPlayer module.
|
||||
\param sample pointer to the sample to be played
|
||||
\param size number of elements in the sample array
|
||||
\param sample_rate audio engine sample rate
|
||||
*/
|
||||
void Init(float* sample, int size, float sample_rate);
|
||||
|
||||
/** Processes the granular player.
|
||||
\param speed playback speed. 1 is normal speed, 2 is double speed, 0.5 is half speed, etc. Negative values play the sample backwards.
|
||||
\param transposition transposition in cents. 100 cents is one semitone. Negative values transpose down, positive values transpose up.
|
||||
\param grain_size grain size in milliseconds. 1 is 1 millisecond, 1000 is 1 second. Does not accept negative values. Minimum value is 1.
|
||||
*/
|
||||
float Process(float speed, float transposition, float grain_size);
|
||||
|
||||
private:
|
||||
//Wraps an index to the size of the sample array
|
||||
uint32_t WrapIdx(uint32_t idx, uint32_t size);
|
||||
|
||||
//Converts cents(1/100th of a semitone) to a ratio
|
||||
float CentsToRatio(float cents);
|
||||
|
||||
//Converts milliseconds to number of samples
|
||||
float MsToSamps(float ms, float samplerate);
|
||||
|
||||
//Inverts the phase of the phasor if the frequency is negative, mimicking pure data's phasor~ object
|
||||
float NegativeInvert(Phasor* phs, float frequency);
|
||||
|
||||
|
||||
float* sample_; //pointer to the sample to be played
|
||||
float sample_rate_; //audio engine sample rate
|
||||
int size_; //number of elements in the sample array
|
||||
float grain_size_; //grain size in milliseconds
|
||||
float speed_; //processed playback speed.
|
||||
float transposition_; //processed transpotion.
|
||||
float sample_frequency_;
|
||||
float cosEnv_[256] = {0}; //cosine envelope for crossfading between grains
|
||||
float
|
||||
idxTransp_; // Adjusted Transposition value contribution to idx of first grain
|
||||
float
|
||||
idxTransp2_; // Adjusted Transposition value contribution to idx of second grain
|
||||
float idxSpeed_; // Adjusted Speed value contribution to idx of first grain
|
||||
float
|
||||
idxSpeed2_; // Adjusted Speed value contribution to idx of second grain
|
||||
float sig_; // Output of first grain
|
||||
float sig2_; // Output of second grain
|
||||
|
||||
uint32_t idx_; // Index of first grain
|
||||
uint32_t idx2_; // Index of second grain
|
||||
|
||||
Phasor phs_; // Phasor for speed
|
||||
Phasor phsImp_; // Phasor for transposition
|
||||
Phasor phs2_; // Phasor for speed
|
||||
Phasor phsImp2_; // Phasor for transposition
|
||||
};
|
||||
} // namespace daisysp
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user