示例#1
0
文件: midi.go 项目: rakyll/sigourney
func initMidi() {
	s, err := portmidi.NewInputStream(portmidi.DeviceId(*midiDevice), 1024)
	if err != nil {
		log.Println(err)
		return
	}
	go midiLoop(s)
}
示例#2
0
func (w *watcher) Run() (err error) {
	midiIn, err := portmidi.NewInputStream(w.midiport, 1024)
	if err != nil {
		return
	}
	events := midiIn.Listen()
	for e := range events {
		w.HandleEvent(&e)
	}
	return nil
}
示例#3
0
// Open opens a connection Launchpad and initializes an input and output
// stream to the currently connected device. If there are no
// devices are connected, it returns an error.
func Open() (*Launchpad, error) {
	input, output, err := discover()
	if err != nil {
		return nil, err
	}

	var inStream, outStream *portmidi.Stream
	if inStream, err = portmidi.NewInputStream(input, 1024); err != nil {
		return nil, err
	}
	if outStream, err = portmidi.NewOutputStream(output, 1024, 0); err != nil {
		return nil, err
	}
	return &Launchpad{inputStream: inStream, outputStream: outStream}, nil
}
示例#4
0
func ExampleStream_ReadSysExBytes() {
	in, err := portmidi.NewInputStream(portmidi.DefaultInputDeviceID(), 1024)
	if err != nil {
		log.Fatal(err)
	}

	msg, err := in.Read(1024)
	if err != nil {
		log.Fatal(err)
	}

	for i, b := range msg {
		fmt.Printf("SysEx message byte %d = %02x\n", i, b)
	}
}
示例#5
0
func initMidi() {
	device := portmidi.DeviceId(*midiDevice)
	if device == -1 {
		device = portmidi.GetDefaultInputDeviceId()
	}
	s, err := portmidi.NewInputStream(device, 1024)
	if err != nil {
		log.Println(err)
		return
	}
	if s == nil {
		log.Println("could not initialize MIDI input device")
		return
	}
	go midiLoop(s)
}
示例#6
0
func ExampleStream_Poll() {
	in, err := portmidi.NewInputStream(portmidi.DefaultInputDeviceID(), 1024)
	if err != nil {
		log.Fatal(err)
	}

	result, err := in.Poll()
	if err != nil {
		log.Fatal(err)
	}

	if result {
		fmt.Println("New messages in the queue!")
	} else {
		fmt.Println("No new messages in the queue :(")
	}
}
示例#7
0
文件: midi.go 项目: boynton/midi-ell
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
}
示例#8
0
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()
}
示例#9
0
// Start begins the Sound by opening two goroutines - one to take a set of active notes and convert
// it into sampled sine waves at the right frequencies, and the second to to listen to the midi input
// stream of events and convert that into the live set of active notes.
func (s *MidiInput) Start() {
	fmt.Println("Starting the MIDI sound's channel...")
	s.samples = make(chan float64)
	s.running = true

	// Goroutine to convert the s.notes set to samples.
	go func(midi *MidiInput) {
		fmt.Printf("  MIDI generation begun!\n")
		atNano := float64(time.Now().UnixNano())

		ticker := time.NewTicker(tickerDuration)
		defer ticker.Stop()

		for now := range ticker.C {
			if !midi.running {
				break
			}

			nowNano := float64(now.UnixNano())
			for ; atNano < nowNano && midi.running; atNano += nsPerCycle {
				if s.notes.IsEmpty() {
					if midi.running {
						midi.samples <- 0.0
					}
				} else {
					cycleAtMult := atNano * nsToSeconds
					value := 0.0
					for _, note := range s.notes.List() {
						// TODO(padster): Remove the * -> int64 -> int cast
						cps := midiToHz(int(note.(int64)))
						offset := math.Remainder(cps*cycleAtMult, 1.0) * math.Pi * 2.0
						value += math.Sin(offset)
					}
					if midi.running {
						midi.samples <- value / float64(s.notes.Size())
					}
				}
			}
		}
		close(s.samples)
	}(s)

	// Goroutine for reading from the input:
	go func() {
		fmt.Println("  Opening MIDI stream..")
		in, err := pm.NewInputStream(s.deviceId, 10)
		if err != nil {
			fmt.Printf("Error in reading midi device %d: Ensure portmidi is Initialized, and device is available.\n", s.deviceId)
			panic(err)
		}

		fmt.Println("Listening to stream")
		for event := range in.Listen() {
			// TODO - figure out what event.Data2 is (volumne?) and use it...
			fmt.Printf("Got: %v\n", event)
			if event.Status == noteStart {
				s.notes.Add(int64(event.Data1))
			} else if event.Status == noteEnd {
				s.notes.Remove(int64(event.Data1))
			} else if event.Status == pitchBend {
				s.Stop()
			}
			if !s.running {
				break
			}
		}
	}()
	// TODO(padster): Move goroutines into struct methods?
}