Assembla home | Assembla project page
 

root/bin/pkscmidi

Revision 1, 3.8 kB (checked in by anonymous, 1 year ago)

Imported old repos

  • Property svn:executable set to *
Line 
1 #!/usr/bin/env python
2
3 import sys
4 import os.path
5 import optparse
6 import threading
7 import rtmidi
8 import scosc
9 import scsynth
10
11
12 def die(msg):
13     sys.stderr.write(msg+'\n')
14     sys.exit(1)
15
16
17 def print_ports(midi):
18     ports = range(midi.getPortCount())
19     if ports:
20         for i in ports:
21             print '    [%i]:' % i,midi.getPortName(i)
22     else:
23         print 'NO MIDI PORTS!'
24         sys.exit(0)
25
26
27 def ask_for_port(midi):
28     print_ports(midi)
29     print 'Enter midi device number [0]:',
30     entry = sys.stdin.readline().strip()
31     if entry:
32         return int(entry)
33     else:
34         return 0
35
36
37
38 class Instrument:
39     def __init__(self, server, synthdef, verbose=False):
40         self.notes = {}
41         self.synth_pool = scsynth.IntPool(1000)
42         self.synthdef = synthdef
43         self.server = server
44         self.verbose = verbose
45
46     def note_on(self, key, vel):
47         self.notes[key] = self.synth_pool.get()
48         osc = ('/s_new', self.synthdef, self.notes[key], 1, 0, 'key', key)
49         self.server.sendMsg(*osc)
50         if self.verbose:
51             print '<<<', osc
52
53     def note_off(self, key, vel):
54         if key in self.notes:
55             osc = ('/n_free', self.notes[key])
56             self.server.sendMsg(*osc)
57             if self.verbose:
58                 print '<<<', osc
59
60
61
62 class Collector(threading.Thread):
63     def __init__(self, device, port, server, synthdef, verbose=False):
64         threading.Thread.__init__(self)
65         self.setDaemon(True)
66         self.port = port
67         self.device = device
68         self.instrument = Instrument(server, synthdef)
69         self.running = True
70         self.verbose = verbose
71
72     def quit(self):
73         self.running = False
74
75     def run(self):
76         self.device.openPort(self.port, True)
77         while self.running:
78             midi = self.device.getMessage()
79             if midi:
80                 if self.verbose:
81                     print '>>>', midi
82                 device, key, vel, timestamp = midi
83                 if vel:
84                     self.instrument.note_on(key, vel)
85                 else:
86                     self.instrument.note_off(key, vel)
87
88 def main():
89     parser = optparse.OptionParser()
90     parser.add_option("-S", "--synthdef",
91                       dest="synthdef",
92                       help="name of SynthDef to load and play")
93     parser.add_option("-d", "--defdir",
94                       dest="defdir",
95                       help="dir with scsyndef file")
96     parser.add_option("-H", "--host",
97                       dest="host", default='localhost',
98                       help="host with a running supercollider server")
99     parser.add_option("-p", "--port",
100                       dest="port", default=57110,
101                       help="port to connect to supercollider server")
102     parser.add_option("-v", "--verbose",
103                       dest="verbose", action="store_true",
104                       help="spit OSC responses, etc")
105     parser.add_option("-s", "--spew",
106                       dest="spew", action='store_true',
107                       help="spew OSC commands")
108     options, args = parser.parse_args(sys.argv)
109
110     if options.synthdef is None:
111         die('--synthdef is required')
112
113     server = scosc.Controller((options.host, int(options.port)),
114                               verbose=options.verbose,
115                               spew=options.spew)
116     if options.defdir:
117         fpath = os.path.join(options.defdir, options.synthdef+'.scsyndef')
118         server.sendMsg('/d_load', os.path.expanduser(fpath))
119
120     midi = rtmidi.RtMidiIn()
121     port = ask_for_port(midi)
122     print '\busing port %i' % port
123     collector = Collector(midi, port, server, options.synthdef,
124                           verbose=options.verbose)
125     collector.start()
126     print 'HIT ENTER TO EXIT'
127     sys.stdin.read(1)
128     collector.quit = True
129
130            
131 main()
Note: See TracBrowser for help on using the browser.