30 unsigned numFrames = outputBuffer.mNumFrames;
31 out1 = outputBuffer.buffer(0);
32 out2 = outputBuffer.buffer(1);
33 memset(out1, 0, numFrames *
sizeof(
sample));
34 memset(out2, 0, numFrames *
sizeof(
sample));
36 while (mCloud->gState !=
kFree) {
40 mCloud->gState =
kDSP;
42 for (
Grain * curGrain = mCloud->mPlayingGrains; curGrain != 0;
45 out1 = outputBuffer.buffer(0);
46 out2 = outputBuffer.buffer(1);
47 length = curGrain->numSamples;
48 sample * sPtr = curGrain->samples;
49 for (
unsigned i = 0; i < numFrames; i++) {
50 if (curGrain->time >= curGrain->duration)
52 if (curGrain->delay) {
56 index = (int)(curGrain->position);
59 while (index >= length)
62 durHalf = curGrain->duration * curGrain->env;
63 if (curGrain->time < durHalf)
64 env = (float) curGrain->time / durHalf;
66 env = (
float)(curGrain->duration - curGrain->time)
67 / (curGrain->duration - durHalf);
68 samp *= curGrain->amplitude * env;
70 *out1++ += samp * (1.0f - curGrain->pan);
71 *out2++ += samp * curGrain->pan;
73 curGrain->position += curGrain->rate;
74 curGrain->time += 1.0f;
78 mCloud->gState =
kFree;
92 for (
unsigned i = 0; i <
MAXGRAINS - 1; i++) {
101 logMsg(
"Create grain lists: %d available", count);
126 logMsg(
"Starting grain creation loop");
130 logMsg(
"Grain creation loop exits");
140 printf(
"\tNo free grains\n");
150 newGrain->
time = 0.0f;
162 logMsg(
"Grain creation loop exits 2");
176 Grain *prevGrain, *curGrain, *nextGrain;
178 logMsg(
"Starting grain culling loop");
182 logMsg(
"Grain culling loop exits");
191 while (curGrain != 0) {
201 curGrain = nextGrain;
205 prevGrain = curGrain;
210 logMsg(
"Grain culling loop exits 2");
228 logMsg(
"Starting grain creation/culling threads (%d)",
C_TIME);
232 logMsg(
"Grain threads running");
241 while (curGrain != 0) {
245 curGrain = nextGrain;
void logMsg(const char *format,...)
These are the public logging messages.
float * mSamples
sample buffer pointer
float mWidthBase
stereo width
bool sleepMsec(float dur)
GrainPlayer(GrainCloud *cloud)
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
float pan
stereo pan 0 - 1
float mDurationBase
grain duration base
#define C_TIME
Which kind of accurate timer to use?
Grain * mSilentGrains
shared grain lists - ptr to the free pool (silent)
float sampsPerTick
resolution of hi-res clock(s-rate / 1 billion)
float mVolumeBase
amplitude scale
float mOffsetRange
offset range
float * samples
sample buffer pointer
void startThreads()
method to start-up the create/reap threads
float time
current time (index) in samples
float rate
playback rate (1.0 for normal pitch, < 0 reads backwards)
GrainCloud * mCloud
the cloud I play
float mOffsetBase
starting index offset base
void stopThread(int timeOutMilliseconds)
calculating audio samples
void reset()
reset all grains to silent
Grain * nextGrain
A pointer to the next grain in the linked list.
float mEnvelopeRange
envelope range
void * reapGrains(void *theArg)
float sample
(could be changed to int, or double)
unsigned mNumChannels
my "expected" number of output channels
Grain * mPlayingGrains
ptr to the list of active grains
float mWidthRange
stereo width
float fRandB(float base, float range)
b +- r (base)
static unsigned frameRate()
default frame rate
void * createGrains(void *theArg)
float position
running sample index
CThread * spawnerThread
thread to create grains
float mRateBase
grain rate base
float mDensityBase
grain density base
unsigned delay
initial delay in samples
float mEnvelopeBase
envelope base: 0 = perc, 0.5 = triangle, 1 = reverse perc
virtual int createThread(VoidFcnPtr *func, void *args)=0
unsigned numSamples
of samples in buffer
Grain data structure This implementation uses a linked list data structure. You might want to add a f...
static CThread * MakeThread()
factory method
float mVolumeRange
amplitude range
GrainulatorState gState
granulator state flag
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
float mDensityRange
grain density range
void nextBuffer(Buffer &outputBuffer)
this sums up the list of live grains – very simple
float duration
duration in samples
GrainCloud()
simple constructor
long gNow
clock for accurate timing
float mRateRange
rate random range
bool sleepUsec(float dur)
Misc. global functions in the csl namespace.
GrainCloud – routine for playing clouds under GUI control. This could be called a cloud or a stream...
float mDurationRange
grain duration range
unsigned numSamples
length of sample vector
bool isPlaying
whether I'm on or off
CThread * reaperThread
thread to kill finished grains
bool threadOn
if the thread's running
#define SAFE_MALLOC(ptr, type, len)
Useful Macros.
float amplitude
amplitude scale (0 - 1)
Base class of CSL exceptions (written upper-case). Has a string message.
float env
envelope: 0 = perc, 0.5 = triangle, 1 = reverse perc