Skip to content

Instantly share code, notes, and snippets.

@grejppi
Last active December 28, 2015 02:29
Show Gist options
  • Save grejppi/7428112 to your computer and use it in GitHub Desktop.
Save grejppi/7428112 to your computer and use it in GitHub Desktop.
# Check out <https://github.com/grejppi/wmcv> for a newer version!
from __future__ import (division, print_function)
import sys
# yeah...
if int(sys.version[0]) >= 3:
import os
os.system('python2 {0}'.format(__file__))
sys.exit()
import time
range = xrange
input = raw_input
import cwiid
from cffi import FFI
ffi = FFI()
buttons = [a for a in dir(cwiid) if 'BTN_' in a]
portdef = ('''
typedef struct {
jack_port_t* port;
volatile float cv;
} Port;
Port* ports[24];
uint32_t ports_used;
''')
cdef = ('''
typedef ... jack_port_t;
''' + portdef + '''
void setup (void);
void start (void);
void stop (void);
Port* new_port (const char* name);
''')
source = ('''
#include <jack/jack.h>
jack_client_t* client;
''' + portdef + r'''
int process (jack_nframes_t nframes, void* data) {
jack_nframes_t i;
uint32_t p;
float* buffer;
for (p = 0; p < ports_used; ++p) {
buffer = (float*) jack_port_get_buffer (ports[p]->port, nframes);
for (i = 0; i < nframes; ++i) {
buffer[i] = ports[p]->cv;
}
}
return 0;
}
void setup (void) {
client = jack_client_open ("wmcv", JackNullOption, NULL);
jack_set_process_callback (client, process, NULL);
ports_used = 0;
}
void start (void) {
jack_activate (client);
}
void stop (void) {
uint32_t i;
jack_deactivate (client);
for (i = 0; i < ports_used; ++i) {
free (ports[i]);
ports[i] = NULL;
}
jack_client_close (client);
}
Port* new_port (const char* name) {
Port* p = NULL;
if (ports_used >= 24) {
fprintf (stderr, "24 ports ought to be enough for anybody\n");
} else {
p = (Port*) malloc (sizeof (Port));
p->port = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
p->cv = 0;
}
ports[ports_used++] = p;
return p;
}
''')
ffi.cdef(cdef)
l = ffi.verify(source, libraries=['jack'])
class WiimoteCV(object):
def __init__(self):
l.setup()
self.wm = None
while self.wm is None:
try:
print('Press 1+2 on the Wiimote...')
self.wm = cwiid.Wiimote()
except RuntimeError:
continue
self.wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK
self.rumble()
def start(self):
print('Press A+B on the Wiimote to start...')
while self.wm.state['buttons'] != 12:
time.sleep(0.01)
pass
self.rumble(2)
l.start()
def stop(self):
l.stop()
def create_port(self, name):
return l.new_port(name)
def rumble(self, n=1, t=0.25):
self.wm.rumble = False
for i in range(max(1, n) * 2):
self.wm.rumble = not self.wm.state['rumble']
time.sleep(t)
if __name__ == '__main__':
w = WiimoteCV()
arrows = w.create_port('arrows')
u = w.create_port('up')
r = w.create_port('right')
d = w.create_port('down')
L = w.create_port('left')
b = w.create_port('b')
w.start()
try:
while True:
ta = None
kst = w.wm.state['buttons']
if kst & cwiid.BTN_UP:
ta = u
if kst & cwiid.BTN_RIGHT:
ta = r
if kst & cwiid.BTN_DOWN:
ta = d
if kst & cwiid.BTN_LEFT:
ta = L
if kst & cwiid.BTN_B:
ta = b
u.cv = 1.0 if (ta is u) else 0.0
r.cv = 1.0 if (ta is r) else 0.0
d.cv = 1.0 if (ta is d) else 0.0
L.cv = 1.0 if (ta is L) else 0.0
b.cv = 1.0 if (ta is b) else 0.0
arrows.cv = 1.0 if (ta is not None) else 0.0
time.sleep(0.01)
except KeyboardInterrupt:
w.stop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment