hey, here i have two examples where i have been trying to use a custom envelope played with `Playbuf`

to modulate the frequency of `SinOsc`

in the first example and `GrainSin`

in the second example.

Can i have `GrainSin`

behave like the `SinOsc`

example when using an unipolar envelope or a any other bipolar signal stored in a buffer with `Playbuf`

to modulate its frequency, i cant hear or see any modulation at all in the second example? thanks.

EDIT: Maybe the rate scaling for both examples is wrong. i have no clue at all.

**1.)** Example with SinOsc:

```
// custom granular envelopes
(
~getCustomEnvs = {
var tri = Env([0, 1, 0], [1, 1], \lin);
var perc = Env.perc(0.01, 1, 1, -4);
var customEnvs = [tri, perc];
customEnvs.collect{|env| Buffer.sendCollection(s, env.discretize(2048), 1) };
};
~customEnvs = ~getCustomEnvs.();
)
(
SynthDef(\sinOsc, { |freqBuf|
var maxOverlap = 4;
var tFreq = \tFreq.kr(1);
var trig = Impulse.ar(tFreq);
var grainDur = \overlap.kr(1) / tFreq;
var freq = \freq.kr(440);
var freqEnv = PlayBuf.ar(
numChannels: 1,
bufnum: freqBuf,
rate: freq * \mRatio.kr(2) * BufFrames.kr(freqBuf) * SampleDur.ir * BufDur.kr(freqBuf) / grainDur,
trigger: trig,
loop: 1,
);
var sig = Array.fill(maxOverlap, { |i|
var localTrig, hasTriggered, phase, grainEnv;
localTrig = PulseDivider.ar(trig, maxOverlap, i);
hasTriggered = PulseCount.ar(localTrig) > 0;
phase = Sweep.ar(localTrig, hasTriggered);
grainEnv = IEnvGen.ar(Env(
[0, 1, 0],
[0.5, 0.5],
\sin
), phase / grainDur);
sig = SinOsc.ar(freq * (1 + (freqEnv * \index.kr(4))));
sig = sig * grainEnv;
}).sum;
sig = Pan2.ar(sig, \pan.kr(0), \amp.kr(0.1));
sig = LeakDC.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
)
(
Pdef(\sinOsc,
Pmono(\sinOsc,
\freqBuf, ~customEnvs[1],
\mRatio, 0.01,
\index, 4,
\freq, 440,
\dur, 0.5,
\tFreq, Pfunc{ |ev| ev[\dur].reciprocal },
\overlap, 4.00,
\amp, 0.10,
\out, 0,
)
).play;
)
```

**2.)** Example with GrainSin

```
(
SynthDef(\grainSin, { |freqBuf|
var tFreq = \tFreq.kr(1);
var trig = Impulse.ar(tFreq);
var grainDur = \overlap.kr(1) / tFreq;
var freq = \freq.kr(440);
var freqEnv = PlayBuf.ar(
numChannels: 1,
bufnum: freqBuf,
rate: freq * \mRatio.kr(2) * BufFrames.kr(freqBuf) * SampleDur.ir * BufDur.kr(freqBuf) / grainDur,
trigger: trig,
loop: 1,
);
var sig = GrainSin.ar(
numChannels: 1,
trigger: trig,
dur: grainDur,
freq: freq * (1 + (freqEnv * \index.kr(4))),
);
sig = Pan2.ar(sig, \pan.kr(0), \amp.kr(0.1));
sig = LeakDC.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
)
(
Pdef(\grainSin,
Pmono(\grainSin,
\freqBuf, ~customEnvs[1],
\mRatio, 0.01,
\index, 4,
\freq, 440,
\dur, 0.5,
\tFreq, Pfunc{ |ev| ev[\dur].reciprocal },
\overlap, 4.00,
\amp, 0.10,
\out, 0,
)
).play;
)
```