WiiLi Wiki frontpage Include your post in the News Get links Hoteles Quito
WiiLi.org Forum Index WiiLi.org
a new revolution
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CWiid Wiitar

 
Post new topic   Reply to topic    WiiLi.org Forum Index -> CWiid
View previous topic :: View next topic  
Author Message
zachdotgeek



Joined: 29 Dec 2007
Posts: 1

Digg It
PostPosted: 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;
      }
   }
}

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    WiiLi.org Forum Index -> CWiid All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group