i have been working on these window functions so you could use them for pulsar synthesis with audio rate. As far as I understand the question, it assumes that you would like to free the Synth after one grain for beeing used with `Pbind`

for example. Ive been exploring the possibilties of audio and control rate for microsound in this thread Making transitions with language or server side sequencing

the most basic implementation with the tukey window for pulsar synthesis using audio rate triggers from `Impulse`

and a triggered `Sweep`

for the Phase, would be something like this:

```
(
var tukeyWindow = { |phase, alpha|
var x = 0.5 * (1 - cos(phase * 2pi / alpha));
var y = 0.5 * (1 - cos((phase - 1) * 2pi / alpha));
var w1 = x * (phase < (alpha / 2));
var w2 = (1 - w1) * (phase >= (alpha / 2)) * (phase <= (1 - (alpha / 2)));
var w3 = y * (phase > (1 - (alpha / 2)));
var result = w1 + w2 + w3;
result * (phase < 1);
};
{
var alpha = SinOsc.ar(0.1).linlin(-1, 1, 0.01, 1);
var tFreq = \tFreq.kr(100);
var trig = Impulse.ar(tFreq);
var grainFreq = \grainFreq.kr(400);
var overlap = \overlap.kr(4).clip(0, grainFreq / tFreq);
var phase = Sweep.ar(trig, grainFreq);
var windowPhase = phase / overlap;
var grainWindow = tukeyWindow.(windowPhase, alpha);
var sig = sin(phase * 2pi);
sig = sig * grainWindow;
sig!2 * 0.1;
}.play;
)
```

you could also swap `sin(phase * 2pi)`

for `BufRd`

to use other waveforms for the pulsaret:

```
(
var tukeyWindow = { |phase, alpha|
var x = 0.5 * (1 - cos(phase * 2pi / alpha));
var y = 0.5 * (1 - cos((phase - 1) * 2pi / alpha));
var w1 = x * (phase < (alpha / 2));
var w2 = (1 - w1) * (phase >= (alpha / 2)) * (phase <= (1 - (alpha / 2)));
var w3 = y * (phase > (1 - (alpha / 2)));
var result = w1 + w2 + w3;
result * (phase < 1);
};
SynthDef(\basic_pulsar, { |sndBuf|
var tFreq = \tFreq.kr(100);
var trig = Impulse.ar(tFreq);
var grainFreq = \freq.kr(400);
var phase = Sweep.ar(trig, grainFreq);
var overlap = \overlap.kr(3).clip(0, grainFreq / tFreq);
var windowPhase = phase / overlap;
var alpha = SinOsc.ar(0.1).linlin(-1, 1, 0.01, 1);
var grainWindow = tukeyWindow.(windowPhase, alpha);
var sig = BufRd.ar(
numChannels: 1,
bufnum: sndBuf,
phase: phase * BufFrames.kr(sndBuf),
loop: 1,
interpolation: 4
);
sig = sig * grainWindow * \amp.kr(-15.dbamp);
sig = Pan2.ar(sig, \pan.kr(0));
OffsetOut.ar(\out.kr(0), sig);
}).add;
)
~sndBuf = Buffer.loadCollection(s, Signal.sineFill(4096, [1,0], 0!2));
Synth(\basic_pulsar, [\sndBuf, ~sndBuf]);
```

You could of course extend this basic setup using `Pulsedivider`

for offsetting the triggers to overlap the windows inside the `SynthDef`

, `Demand`

Ugens to sequence different parameters like spatialization per grain or also fx processing per grain, or use heavy modulation of the basic parameters like trigger frequency, grain frequency and window multiplication (overlap)

EDIT: I think the example for pulsar synthesis from the helpfile of `Osc1`

is a bit misleading in terms of dealing with audio and control rate triggers. I think when wanting to build an granular instrument which is most versatile in terms of timbral transformation its better to use audio rate triggers from `Impulse`

together with `Sweep`

and `Demand`

Ugens. Of course you could also use the ordinary `GrainBuf`

, `GrainSin`

etc. Ugens but these sample and hold each grain when triggered, so you could for example not modulate the window or do FM / PM per grain Frequency instead of phase - #31 by dietcv which is for example cool if you overlap several frequency sweeps for a quasi shepard-tone glissando.

This approach ist not binded to â€śpulsar synthesisâ€ť at all you could use it for all the other granular approaches as well, you just have to change the `BufRd`

implementation:

```
(
var tukeyWindow = { |phase, alpha|
var x = 0.5 * (1 - cos(phase * 2pi / alpha));
var y = 0.5 * (1 - cos((phase - 1) * 2pi / alpha));
var w1 = x * (phase < (alpha / 2));
var w2 = (1 - w1) * (phase >= (alpha / 2)) * (phase <= (1 - (alpha / 2)));
var w3 = y * (phase > (1 - (alpha / 2)));
var result = w1 + w2 + w3;
result * (phase < 1);
};
SynthDef(\basic_granular, { |sndBuf|
var tFreq = \tFreq.kr(1);
var trig = Impulse.ar(tFreq);
var grainFreq = \grainFreq.kr(1);
var phase = Sweep.ar(trig, grainFreq);
var overlap = \overlap.kr(0.5);
var windowPhase = phase / overlap;
var grainWindow = tukeyWindow.(windowPhase, 0.5);
var startPhase = TRand.ar(0, 80000, trig);
var sig = BufRd.ar(
numChannels: 1,
bufnum: sndBuf,
phase: phase * BufSampleRate.kr(sndBuf) + startPhase,
loop: 0,
interpolation: 4
);
sig = sig * grainWindow * \amp.kr(-10.dbamp);
sig = Pan2.ar(sig, \pan.kr(0));
OffsetOut.ar(\out.kr(0), sig);
}).add;
)
~sndBuf = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
Synth(\basic_granular, [\tFreq, 10, \overlap, 0.02, \sndBuf, ~sndBuf]);
```

so i think there is not any real benefit of using `Osc1`

. Because Synthdefs are fixed with evaluation i think its nice to have an additional `OffsetOut`

Ugen for the triggers, send them to a bus and have different modulator SynthDefs using `Demand`

Ugens receiving these triggers to sequence different parameters via `bus.asMap`

.