func (pat *randomNotes) Next() (float32, error) { scale := scales[rand.Intn(len(scales))] if pat.idx%128 == 0 { scale = scales[rand.Intn(numScales)] pat.idx = 0 } pat.idx++ return sc.Midicps(int(scale[rand.Intn(pattern.ScaleLen)]) + 12*(rand.Intn(octaveMax)+octaveMin)), nil }
func main() { const synthName = "sineTone" var synthID int32 var note int var gain, dur float32 // setup supercollider client client, err := sc.NewClient("udp", "127.0.0.1:57111", "127.0.0.1:57110", 5*time.Second) if err != nil { log.Fatal(err) } defaultGroup, err := client.AddDefaultGroup() if err != nil { log.Fatal(err) } err = client.DumpOSC(int32(1)) if err != nil { log.Fatal(err) } def := sc.NewSynthdef(synthName, func(p sc.Params) sc.Ugen { freq := p.Add("freq", 440) gain := p.Add("gain", 0.5) dur := p.Add("dur", 1) bus := sc.C(0) env := sc.EnvGen{ Env: sc.EnvPerc{Release: dur}, LevelScale: gain, Done: sc.FreeEnclosing, }.Rate(sc.KR) sig := sc.SinOsc{Freq: freq}.Rate(sc.AR).Mul(env) return sc.Out{bus, sig}.Rate(sc.AR) }) err = client.SendDef(def) if err != nil { log.Fatal(err) } ticker := time.NewTicker(125 * time.Millisecond) for _ = range ticker.C { synthID = client.NextSynthID() note = rand.Intn(128) gain = rand.Float32() dur = rand.Float32() ctls := map[string]float32{ "freq": sc.Midicps(float32(note)), "gain": gain, "dur": dur, } _, err = defaultGroup.Synth(synthName, synthID, sc.AddToTail, ctls) } }
// FromNote implements poly.Controller. func (dx7 *DX7) FromNote(note *poly.Note) map[string]float32 { var ( ctrls = map[string]float32{"gate": float32(1)} freq = sc.Midicps(note.Note) gain = float32(note.Velocity) / (poly.MaxMIDI * polyphony) ) for op := range ops { ctrls[ctrlName(op, "freq")] = freq ctrls[ctrlName(op, "gain")] = gain ctrls[ctrlName(op, "amt")] = dx7.ctrls["op1amt"] ctrls[ctrlName(op, "freqscale")] = dx7.ctrls["op2freqscale"] ctrls[ctrlName(op, "decay")] = dx7.ctrls["op2decay"] ctrls[ctrlName(op, "sustain")] = dx7.ctrls["op2sustain"] } return ctrls }
func main() { var synthID int32 const synthName = "sineTone" // Set up SuperCollider client. client, err := sc.NewClient("udp", "127.0.0.1:57121", "127.0.0.1:57120", 5*time.Second) if err != nil { log.Fatal(err) } _, err = client.AddDefaultGroup() if err != nil { log.Fatal(err) } err = client.DumpOSC(int32(1)) if err != nil { log.Fatal(err) } def := sc.NewSynthdef(synthName, func(p sc.Params) sc.Ugen { freq := p.Add("freq", 440) gain := p.Add("gain", 0.5) bus := sc.C(0) env := sc.EnvGen{ Env: sc.EnvPerc{}, Done: sc.FreeEnclosing, LevelScale: gain, }.Rate(sc.KR) sig := sc.SinOsc{Freq: freq}.Rate(sc.AR).Mul(env) return sc.Out{bus, sig}.Rate(sc.AR) }) err = client.SendDef(def) if err != nil { log.Fatal(err) } // initialize midi portmidi.Initialize() // this code can be uncommented to discover the // device ID's portmidi comes up with // deviceCount := portmidi.CountDevices() // enc := json.NewEncoder(os.Stdout) // for i := 0; i < deviceCount; i++ { // info := portmidi.GetDeviceInfo(portmidi.DeviceId(i)) // log.Printf("device %d - ", i) // err = enc.Encode(info) // if err != nil { // log.Fatal(err) // } // } // setup midi input stream and listen for midi events in, err := portmidi.NewInputStream(3, 1024) if err != nil { log.Fatal(err) } ch := in.Listen() for event := range ch { if event.Status == 144 { // MIDI note log.Printf("Note %-3d Velocity %-3d\n", event.Data1, event.Data2) if event.Data2 > 0 { // Note On synthID = client.NextSynthID() ctls := map[string]float32{ "freq": sc.Midicps(float32(event.Data1)), "gain": float32(event.Data2 / 127.0), } _, err = client.Synth(synthName, synthID, sc.AddToTail, sc.DefaultGroupID, ctls) } } } portmidi.Terminate() }