func Generate(ctx sound.Context) (left, right chan float64) { rand.Seed(time.Now().UnixNano()) melodyParts := make(chan chan float64) bassParts := make(chan chan float64) go func() { for { var octave int x := rand.Float64() if x < 0.3 { octave = 4 } else { octave = 5 } root := music.MakeNote(music.D, octave) scale := music.Scale{Root: root, Intervals: music.HarmonicMinor} var n int x = rand.Float64() if x < 0.2 { n = 3 } else if x < 0.4 { n = 6 } else if x < 0.6 { n = 12 } else if x < 0.8 { n = 18 } else { n = 24 } melodyParts <- genMelodyArpeggio(ctx, scale, n) } }() go func() { for { var octave int x := rand.Float64() if x < 0.3 { octave = 3 } else { octave = 2 } root := music.MakeNote(music.D, octave) scale := music.Scale{Root: root, Intervals: music.HarmonicMinor} var n int x = rand.Float64() if x < 0.2 { n = 3 } else if x < 0.4 { n = 6 } else if x < 0.6 { n = 9 } else if x < 0.8 { n = 12 } else { n = 18 } bassParts <- genBassArpeggio(ctx, scale, n) } }() melody := playMelodySynth(ctx, ctx.AppendStream(melodyParts)) bass := playBassSynth(ctx, ctx.AppendStream(bassParts)) melodyLeft, melodyRight := ctx.Fork2(melody) bassLeft, bassRight := ctx.Fork2(bass) left = ctx.TakeDuration( ctx.Add( ctx.Mul(melodyLeft, ctx.Const(0.4)), ctx.Mul(bassLeft, ctx.Const(0.6)), ), time.Second*300, true, ) right = ctx.TakeDuration( ctx.Add( ctx.Mul(melodyRight, ctx.Const(0.6)), ctx.Mul(bassRight, ctx.Const(0.4)), ), time.Second*300, true, ) return left, right }