func TestSequencer(t *testing.T) { engine := lightning.NewEngine() seq := newSequencer(engine, 128, 480) err := seq.Start() if err != nil { t.Fatal(err) } for pos := range seq.PosChan { if pos > 16 { break } } err = seq.Stop() if err != nil { t.Fatal(err) } }
// sequencerEndpoint creates a websocket handler for the /sequencer endpoint func (self *server) sequencerEndpoint(conn *websocket.Conn) { var err error mc := make(chan interface{}) ec := make(chan error) go self.readMessages(conn, mc, ec) for { select { case err := <-ec: if err == io.EOF { // the client closed the connection goto CloseConnection } if err != nil { panic(err) } case msg := <-mc: if s, isString := msg.(string); isString { // start or stop if s == "start" { err = self.seq.Start() if err != nil { panic(err) } } else if s == "stop" { err = self.seq.Stop() if err != nil { panic(err) } } else { panic(fmt.Errorf("unrecognized sequencer command %s", s)) } } else if f, isFloat := msg.(float64); isFloat { // tempo self.seq.SetTempo(float32(f)) } case pos := <-self.seq.PosChan: _, err = conn.Write([]byte(strconv.FormatUint(pos, 10))) if err == io.EOF { goto CloseConnection } if err != nil { panic(err) } } } CloseConnection: } // close closes the audio engine func (self *server) close() { self.engine.Close() } // newServer creates a websocket/rest server that manages the bulk // of lightningd functionality func newServer(www string) (*server, error) { srv := new(server) srv.engine = lightning.NewEngine() // initialize tempo to 120 bpm (a typical // starting point for sequencers) srv.seq = newSequencer(srv.engine, patternLength, 120) // initialize samples srv.samples = newSamples(srv.engine) // setup handlers under default ServeMux fileServer := http.FileServer(http.Dir(www)) // static file server http.Handle("/", fileServer) // http endpoints http.HandleFunc("/samples", srv.samples.list()) // websocket endpoints http.Handle("/sample/play", srv.samples.play()) http.Handle("/sequencer", websocket.Handler(srv.sequencerEndpoint)) // http.Handle("/note/remove", srv.noteRemove()) // http.Handle("/pattern/play", srv.patternPlay()) // http.Handle("/pattern/stop", srv.patternStop()) // http.Handle("/pattern/position", srv.patternPosition()) /* /sequencer */ return srv, nil }