zachdotgeek
Joined: 29 Dec 2007 Posts: 1
Digg It |
Posted: Sat Dec 29, 2007 1:53 pm Post subject: CWiid Wiitar |
|
|
I could not find a wiitar program for Linux, so I hacked wmdemo into one. To use it, copy the code to a file (such as wiitar.c), change MIDI_DEVICE to the location of your midi device, then compile it with | Code: | | gcc -lcwiid wiitar.c -o wiitar | .
| Code: |
// Wiitar on CWiid
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/soundcard.h>
#include <cwiid.h>
#include <math.h>
//Nasty Global Variables
unsigned char led_state = 0; //State of the wiimote
int midifd; //Midi output
int buttons; //Button State
int nunchuk_y; //Accelerometer
int nunchuk_x; //Joystick
int nunchuk_vol; //Joystick Y
int nunchuk_btns;
unsigned short strum_both = 1; //Strum up or Down?
//***************************************
// * IMPORTANT *
// Change this to your midi sound card device
#define MIDI_DEVICE "/dev/snd/midiC2D0"
#define MESSAGE \
"Strum with the wiimote. Control pitch with the Nunchuk.\n" \
"Up and down on the joystick changes volume. B, A, Down, or Up\n"\
"changes the base pitch. Z plays cords. C allows free pitch selection.\n"\
"1 changes to 1 way strumming (Default). 2 changes to 2 way strumming.\n"\
"Press 'q' to quit.\n\n"
#define DOWN_VALUE 130
#define UP_VALUE 125
int precision = 8;
cwiid_mesg_callback_t cwiid_callback;
void stop_notes();
cwiid_err_t err;
void err(cwiid_wiimote_t *wiimote, const char *s, va_list ap)
{
if (wiimote) printf("%d:", cwiid_get_id(wiimote));
else printf("-1:");
vprintf(s, ap);
printf("\n");
}
int main(int argc, char *argv[])
{
cwiid_wiimote_t *wiimote; /* wiimote handle */
struct cwiid_state state; /* wiimote state */
bdaddr_t bdaddr; /* bluetooth device address */
unsigned char mesg = 0;
unsigned char led_state = 0;
unsigned char rpt_mode = 0;
unsigned char rumble = 0;
int exit = 0;
cwiid_set_err(err);
char* device = MIDI_DEVICE ; //TODO: Better way to choose the device
unsigned char data[3] = {0x90, 60, 127};
// step 1: open the OSS device for writing
midifd = open(device, O_WRONLY, 0);
if (midifd < 0) {
printf("Error: cannot open %s\n", device);
return -1;
}
/* Connect to address given on command-line, if present */
if (argc > 1) {
str2ba(argv[1], &bdaddr);
}
else {
bdaddr = *BDADDR_ANY;
}
printf("%s",MESSAGE);
/* Connect to the wiimote */
printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
if (!(wiimote = cwiid_open(&bdaddr, 0))) {
fprintf(stderr, "Unable to connect to wiimote\n");
return -1;
}
fprintf(stderr,"Connected!");
if (cwiid_set_mesg_callback(wiimote, cwiid_callback)) {
fprintf(stderr, "Unable to set message callback\n");
}
//Enable Messages
if (cwiid_enable(wiimote, CWIID_FLAG_MESG_IFC)) {
fprintf(stderr, "Error enabling messages\n");
}
//fprintf(stderr,"Messages Enabled");
//Report Accelerometer Data
if (cwiid_set_rpt_mode(wiimote, CWIID_RPT_ACC|CWIID_RPT_BTN|CWIID_RPT_NUNCHUK)) {
fprintf(stderr, "Error setting report mode\n");
}
//Keep it running
while (!exit) {
switch (getchar()) {
case 'q':
exit =1;
break;
}
}
stop_notes();
//Cleanup
if (cwiid_close(wiimote)) {
fprintf(stderr, "Error on wiimote disconnect\n");
return -1;
}
close(midifd);
return 0;
}
void set_note(cwiid_wiimote_t *wiimote, char* data) {
data[0]=0x90; //Note On Signal
data[2]=(nunchuk_vol<127) ? nunchuk_vol : 127; //Volume
switch (buttons) {
case 0: //No Buttons
data[1]=36;
break;
case 4: //B
data[1]=48;
break;
case 8: //A
data[1]=60; //Middle C
break;
case 1024: //Down
data[1]=72;
break;
case 2048: //Up
data[1]=84;
break;
}
if ((nunchuk_btns == 0) || (nunchuk_btns == 1)) {
data[1]+=(100-nunchuk_y)/precision;
} else { //C
data[1]+=100-abs(nunchuk_y);
}
}
void stop_notes() {
printf("stopping notes\n");
int i;
for (i=0;i<=127;i++) {
unsigned char data[3] = {0x80, i, 127};
write(midifd, data, sizeof(data));
}
}
void strum(cwiid_wiimote_t *wiimote, time_t this_time, int y) {
static time_t last_time;
time_t interval;
interval = this_time -last_time;
static unsigned char data[9]= {0x90, 60,127 ,0x90, 60+4, 127,0x90, 60+7, 127};
//Clear last note
data[0]=0x80;
data[3]=0x80;
data[6]=0x80;
write(midifd, data, sizeof(data));
set_note(wiimote,data);
data[0]=0x90;
data[3]=0x90;
data[6]=0x90;
if (abs(interval) >= 1 ) {
//printf("Strum. Y:%d Time diff:%ld this:%ld last:%ld", y, interval,this_time,last_time);
if ((nunchuk_btns == 1) || (nunchuk_btns==3)) {
//Cords
//data2 = {0x90, data[1], data[2],0x90, data[1]+4, data[2],0x90, data[1]+7, data[2]};
data[4]=data[1]+4;
data[7]=data[1]+7;
data[5]=data[2];
data[8]=data[2];
write(midifd, data, sizeof(data));
} else {
write(midifd, data, sizeof(data)/3);
}
}
last_time = this_time;
}
void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
union cwiid_mesg mesg[], struct timespec *timestamp)
{
int i, j;
int valid_source;
//To determine whether to display pitch data
static unsigned char data[3] = {0x90, 60, 127};
static unsigned char last_pitch;
for (i=0; i < mesg_count; i++)
{
switch (mesg[i].type) {
case CWIID_MESG_BTN:
printf("Button Report: %d\n", mesg[i].btn_mesg.buttons);
buttons = mesg[i].btn_mesg.buttons;
if (buttons == 512) {
stop_notes();
}
if (buttons == 1) {
strum_both = 0;
printf("2 Directional Strumming\n");
}
if (buttons == 2) {
strum_both = 1;
printf("1 Directional Strumming\n");
}
break;
case CWIID_MESG_ACC:
if ((led_state!=1) && (mesg[i].acc_mesg.acc[CWIID_Y] > DOWN_VALUE)) { //Strum Down
led_state=1;
strum(wiimote, timestamp->tv_nsec, mesg[i].acc_mesg.acc[CWIID_Y]);
} else if ((led_state!=2) && (mesg[i].acc_mesg.acc[CWIID_Y] < UP_VALUE)) { //Strum Up
led_state=2;
if (strum_both!=1) {
strum(wiimote, timestamp->tv_nsec, mesg[i].acc_mesg.acc[CWIID_Y]);
}
}
break;
case CWIID_MESG_NUNCHUK:
nunchuk_y=mesg[i].nunchuk_mesg.acc[CWIID_Y];
nunchuk_vol = mesg[i].nunchuk_mesg.stick[CWIID_Y];
nunchuk_x = mesg[i].nunchuk_mesg.stick[CWIID_X];
nunchuk_btns = mesg[i].nunchuk_mesg.buttons;
//Display Current Pitch
set_note(wiimote,data);
if (data[1]!=last_pitch){
printf("Pitch:%d\n",data[1]);
last_pitch=data[1];
}
break;
case CWIID_MESG_ERROR:
if (cwiid_close(wiimote)) {
fprintf(stderr, "Error on wiimote disconnect\n");
exit(-1);
}
fprintf(stderr, "ERROR");
exit(0);
break;
default:
printf("Unknown Report");
break;
}
}
}
|
|
|