```

```

### #04 Loops

A second building block of Dittytoy is the loop. You can use a loop to define a repeating music pattern.

Each loop runs in its own worker/thread. So by using multiple loops, you can parallelize your ditty, which makes it a convenient way to optimize your ditty if it doesn't perform well.

dittytoy.net/syntax#loops

#dittytoy #tutorial

```// #04 Loops. DittyToy 2022.
//
// https://dittytoy.net/ditty/07455f0c58
//
// A second building block of Dittytoy is the loop. You can use a loop to define a repeating music pattern.
//
// Each loop runs in its own worker/thread. So by using multiple loops, you can parallelize your
// ditty, which makes it a convenient way to optimize your ditty if it doesn't perform well.
//
// A loop supports the following options by default:
//
// - name (optional, the name of the loop)
// - amp (volume, default: 1)
// - pan (panning, -1 to 1, default: 0)
// - sync (in ticks, optional)
//
// https://dittytoy.net/syntax#loops
//

const noise  = synth.def( (phase, env, tick, options) => (Math.random() * 2 - 1) * env.value, { env: adsr2 } );
const kick   = synth.def( (phase, env, tick, options) => Math.sin(phase * 2 * Math.PI * (1.5 - tick * 4)) * env.value, { attack: 0.025, release: 0.15, env: adsr2 });

ditty.bpm = 120;

loop( (loopCount) => {

if (loopCount % 4 < 3) kick.play(c3);

}, { name: 'kick', sync: 1 });

loop( (loopCount) => {

noise.play(c3, { attack: 0.0125, release: 0.075, amp: .05 + Math.random() * 0.05 });
sleep(0.25);

}, { name: 'hi-hat' });

loop( (loopCount) => {

for (let i=0; i<4; i++) {
sine.play(c4, { attack: 0.01, release: 0.25,  duration: 0.125, pan: Math.random() * 2 - 1, amp: 1.0 });
sleep( 0.25 );
}

sine.play(d4, { attack: 0.01, release: 0.25,  duration: 0.25 }); // attack and release in seconds, duration in ticks
sleep(0.5); // sleep in ticks

sine.play(f4, { attack: 0.01, release: 0.75,  duration: 0.25 });
sleep(0.5);

}, { name: 'melody' });
```