func midiListen(argv []*ell.Object) (*ell.Object, error) { ch := ell.Null midiMutex.Lock() if midiIn != nil { ch = ell.Channel(int(midiBufsize), "midi") go func(s *portmidi.Stream, ch *ell.Object) { for { time.Sleep(10 * time.Millisecond) events, err := s.Read(1024) if err != nil { continue } channel := ell.ChannelValue(ch) if channel != nil { for _, ev := range events { ts := (float64(ev.Timestamp) / 1000) + midiBaseTime st := ev.Status d1 := ev.Data1 d2 := ev.Data2 channel <- ell.List(ell.Number(ts), ell.Number(float64(st)), ell.Number(float64(d1)), ell.Number(float64(d2))) } } } }(midiIn, ch) } midiMutex.Unlock() return ch, nil }
func midiInit() error { ell.DefineFunctionKeyArgs("midi-open", midiOpen, ell.NullType, []*ell.Object{ell.StringType, ell.StringType, ell.NumberType}, []*ell.Object{ell.EmptyString, ell.EmptyString, ell.Number(1024)}, []*ell.Object{inputKey, outputKey, bufsizeKey}) ell.DefineFunction("midi-write", midiWrite, ell.NullType, ell.NumberType, ell.NumberType, ell.NumberType) ell.DefineFunction("midi-close", midiClose, ell.NullType) ell.DefineFunction("midi-listen", midiListen, ell.ChannelType) return nil }
func midiOpen(argv []*ell.Object) (*ell.Object, error) { // defaultInput := "USB Oxygen 8 v2" // defaultOutput := "IAC Driver Bus 1" latency := int64(10) if !midiOpened { err := portmidi.Initialize() if err != nil { return nil, err } midiOpened = true midiInDevice = ell.StringValue(argv[0]) midiOutDevice = ell.StringValue(argv[1]) midiBufsize = ell.Int64Value(argv[2]) outdev, outname := findMidiOutputDevice(midiOutDevice) out, err := portmidi.NewOutputStream(outdev, midiBufsize, latency) if err != nil { return nil, err } midiOut = out midiOutDevice = outname if midiInDevice != "" { indev := findMidiInputDevice(midiInDevice) if indev >= 0 { in, err := portmidi.NewInputStream(indev, midiBufsize) if err != nil { return nil, err } midiIn = in } } midiBaseTime = ell.Now() } result := ell.MakeStruct(4) if midiInDevice != "" { ell.Put(result, inputKey, ell.String(midiInDevice)) } if midiOutDevice != "" { ell.Put(result, outputKey, ell.String(midiOutDevice)) } ell.Put(result, bufsizeKey, ell.Number(float64(midiBufsize))) return result, nil }