func genMelodyArpeggio(ctx sound.Context, scale music.Scale, n int) (stream chan float64) { var parts []chan float64 root := scale.Root for i := 0; i < n; i++ { if i+1 < n && rand.Float64() < 0.01 { from := scale.Root nextNote(&scale, root) to := scale.Root nextNote(&scale, root) part := genSlideEnvelope(ctx, from, to, time.Second/4) parts = append(parts, part) } else { note := scale.Root nextNote(&scale, root) part := ctx.TakeDuration(ctx.Const(note.Frequency()), time.Second/8, false) parts = append(parts, part) } } return ctx.Append(parts...) }
func FrequencyEnvelope(ctx sound.Context) (stream chan float64) { var parts []chan float64 for _, note := range Notes { part := ctx.TakeDuration(ctx.Const(note.Frequency()), NoteDuration, false) parts = append(parts, part) } return ctx.Append(parts...) }
func genBassArpeggio(ctx sound.Context, scale music.Scale, n int) (stream chan float64) { var parts []chan float64 root := scale.Root for i := 0; i < n; i++ { note := scale.Root nextNote(&scale, root) if rand.Float64() < 0.05 { part := ctx.TakeDuration( ctx.Mul( ctx.Const(note.Frequency()), ctx.Add( // Add a slight vibrato effect ctx.Mul( ctx.Sine(ctx.Const(24)), ctx.Const(0.01), ), ctx.Const(1.0), ), ), time.Second*3/8, false, ) parts = append(parts, part) } else if rand.Float64() < 0.05 { part1 := ctx.TakeDuration( ctx.Const(note.Frequency()), time.Second/8, false, ) part2 := ctx.TakeDuration( ctx.Const(note.Frequency()), time.Second/8, false, ) parts = append(parts, part1) parts = append(parts, ctx.TakeDuration(ctx.Silence(), time.Second/8, false)) parts = append(parts, part2) } else { part := ctx.TakeDuration( ctx.Const(note.Frequency()), time.Second/8, false, ) parts = append(parts, part) parts = append(parts, ctx.TakeDuration(ctx.Silence(), time.Second/4, false)) } } return ctx.Append(parts...) }