func GenerateBassMelody() (notes chan music.Note) { notes = make(chan music.Note) 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 } for i := 0; i < n; i++ { notes <- scale.Root NextNote(&scale, root) } } }() return notes }
// A simple C major scale played on a sine oscillator. // A single call to 'Sine' is used, with its frequency modulated through each of // the notes. package main import ( "github.com/kierdavis/gosound/frontend" "github.com/kierdavis/gosound/music" "github.com/kierdavis/gosound/sound" "time" ) var Notes = []music.Note{ music.MakeNote(music.C, 4), music.MakeNote(music.D, 4), music.MakeNote(music.E, 4), music.MakeNote(music.F, 4), music.MakeNote(music.G, 4), music.MakeNote(music.A, 4), music.MakeNote(music.B, 4), music.MakeNote(music.C, 5), // The last note is duplicated so that the frequency envelope will extend // longer than necessary. This is to ensure that the oscillator continues // playing once 8*NoteDuration has elapsed, so that we can find a zero // crossing to stop at. music.MakeNote(music.C, 5), } const NoteDuration = (time.Second * 3) / 10
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 }