| 55 | } |
| 56 | |
| 57 | void Granulator::ProcessFrame(double time, ChannelBuffer* buffer, int bufferLength, double offset, float speed, float* output) |
| 58 | { |
| 59 | if (time + gInvSampleRateMs >= mNextGrainSpawnMs) |
| 60 | { |
| 61 | double startFromMs = mNextGrainSpawnMs; |
| 62 | if (startFromMs < time - 1000) //must have recently started processing, reset |
| 63 | startFromMs = time; |
| 64 | SpawnGrain(mNextGrainSpawnMs, offset, buffer->NumActiveChannels() == 2 ? mWidth : 0, speed); |
| 65 | mNextGrainSpawnMs = startFromMs + mGrainLengthMs * 1 / mGrainOverlap * ofRandom(1 - mSpacingRandomize / 2, 1 + mSpacingRandomize / 2); |
| 66 | } |
| 67 | |
| 68 | for (int i = 0; i < MAX_GRAINS; ++i) |
| 69 | mGrains[i].Process(time, buffer, bufferLength, output); |
| 70 | |
| 71 | for (int ch = 0; ch < buffer->NumActiveChannels(); ++ch) |
| 72 | { |
| 73 | if (mGrainOverlap > 4) |
| 74 | output[ch] *= ofMap(mGrainOverlap, MAX_GRAINS, 4, .5f, 1); //lower volume on dense granulation, starting at 4 overlap |
| 75 | output[ch] = mBiquad[ch].Filter(output[ch]); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | void Granulator::SpawnGrain(double time, double offset, float width, float speed) |
| 80 | { |
no test coverage detected