SHARE
TWEET

Corsair K70 Spectrum Graph Visualization

CalcProgrammer1 Oct 13th, 2014 5,512 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <usb.h>
  4. #include <math.h>
  5. #include <AL/al.h>
  6. #include <AL/alc.h>
  7. #include <SDL/SDL.h>
  8. #include <SDL/SDL_gfxPrimitives.h>
  9. #include "chuck_fft.h"
  10. #include "serial_port.h"
  11. #include "fanbus.h"
  12.  
  13. #define FALSE 0
  14.  
  15. serial_port ports[2];
  16. fanbus bus1;
  17.  
  18. static struct usb_device *find_device(uint16_t vendor, uint16_t product);
  19.  
  20. static int init_keyboard();
  21.  
  22. static void update_keyboard();
  23.  
  24. static void set_led( int x, int y, int r, int g, int b );
  25.  
  26. static int red_leds[] = { 0x10, 0x13, 0x16, 0x19 };
  27. static int grn_leds[] = { 0x11, 0x14, 0x17, 0x1A };
  28. static int blu_leds[] = { 0x12, 0x15, 0x18, 0x1B };
  29.  
  30. char red_val[144];
  31. char grn_val[144];
  32. char blu_val[144];
  33.  
  34. char data_pkt[5][64] = { 0 };
  35.  
  36. unsigned char position_map[] = {
  37.   137,  8, 20,255,
  38.         0, 12, 24, 36, 48, 60, 72, 84, 96,108,120,132,  6, 18, 30, 42, 32, 44, 56, 68,255,
  39.         1, 13, 25, 37, 49, 61, 73, 85, 97,109,121,133,  7, 31, 54, 66, 78, 80, 92,104,116,255,
  40.         2, 14, 26, 38, 50, 62, 74, 86, 98,110,122,134, 90,102, 43, 55, 67,  9, 21, 33,128,255,
  41.         3, 15, 27, 39, 51, 63, 75, 87, 99,111,123,135,126, 57, 69, 81,128,255,
  42.         4, 28, 40, 52, 64, 76, 88,100,112,124,136, 79,103, 93,105,117,140,255,
  43.         5, 17, 29, 53, 89,101,113, 91,115,127,139,129,141,140,255,
  44. };
  45.  
  46. float size_map[] = {
  47.         -15.5, 1, 1, -2.5, 1, -2, 0,
  48.         1, -.5, 1, 1, 1, 1, -.75, 1, 1, 1, 1, -.75, 1, 1, 1, 1, -.5, 1, 1, 1, -.5, 1, 1, 1, 1, 0,
  49.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, -.5, 1, 1, 1, -.5, 1, 1, 1, 1, 0,
  50.         1.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.5, -.5, 1, 1, 1, -.5, 1, 1, 1, 1, 0,
  51.         1.75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2.25, -4, 1, 1, 1, 1, 0,
  52.         2.25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2.75, -1.5, 1, -1.5, 1, 1, 1, 1, 0,
  53.         1.5, 1, 1.25, 6.5, 1.25, 1, 1, 1.5, -.5, 1, 1, 1, -.5, 2, 1, 1, 0,
  54. };
  55.  
  56. unsigned char led_matrix[7][92];
  57.  
  58. unsigned char led_waveform[7][92];
  59.  
  60. struct usb_device *dev;
  61. struct usb_dev_handle *handle;
  62.  
  63. float normalizeFFT(float fftin)
  64. {
  65.     if(fftin > 0)
  66.     {
  67.         return 20.0f*log10(fftin);
  68.     }
  69.     else
  70.     {
  71.         return 0;
  72.     }
  73. }
  74.  
  75. int main(int argc, char *argv[])
  76. {
  77.     float amplitude = 10.0f;
  78.     unsigned char red, grn, blu;
  79.     unsigned long sdl_ticks = 0;
  80.     unsigned char buffer[256];
  81.     ALint sample;
  82.     float fft[256];
  83.     unsigned char charfft[256];
  84.     float win[256];
  85.     float fftavg;
  86.     int level;
  87.     SDL_Surface* wavs = NULL;
  88.     SDL_Surface* screen = NULL;
  89.     SDL_Event event;
  90.  
  91.     SDL_Init( SDL_INIT_EVERYTHING );
  92.     screen = SDL_SetVideoMode( 256, 256, 32, SDL_HWSURFACE );
  93.     wavs = SDL_SetVideoMode( 256, 256, 32, SDL_HWSURFACE );
  94.     SDL_WM_SetCaption("FanBus Audio Visualizer", NULL);
  95.  
  96.     ALCdevice *device = alcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO8, 256);
  97.     alcCaptureStart(device);
  98.  
  99.     hanning(win, 256);
  100.  
  101.  
  102.     if( ports[0].serial_open("/dev/ttyS4", 38400) == FALSE )
  103.     {
  104.         return 0;
  105.     }
  106.  
  107.     bus1.fanbus_set_port(&ports[0]);
  108.  
  109.     init_keyboard();
  110.  
  111.     while(1)
  112.     {
  113.             for(int j = 0; j < 92; j++)
  114.             {
  115.             for(int i = 0; i < 256; i++)
  116.             {
  117.                 buffer[i] = 0;
  118.                 charfft[i] = 0;
  119.                 fft[i] = 0;
  120.             }
  121.  
  122.             alcCaptureSamples(device, (ALCvoid *)buffer, 256);
  123.             level = 0;
  124.             for(int i = 0; i < 256; i++)
  125.             {
  126.                 level += abs((int)buffer[i]-128);
  127.                 fft[i] = (buffer[i]-128)*amplitude;
  128.             }
  129.  
  130.             rfft(fft, 256, 1);
  131.             //apply_window(fft, win, 256);
  132.             boxRGBA(wavs, 0, 0, 255, 255, 0, 0, 0, 255);
  133.  
  134.             for(int i = 0; i < 256; i+=2)
  135.             {
  136.                 float fftmag = sqrt((fft[i]*fft[i])+(fft[i+1]*fft[i+1]));
  137.                 fftavg += fftmag;
  138.                 charfft[i] = (unsigned char)fftmag;
  139.                 charfft[i+1] = charfft[i];
  140.             }
  141.             fftavg /= 10;
  142.             for(int i = 0; i < 256; i++)
  143.             {
  144.                 lineRGBA(wavs, i, 255, i, 255-charfft[i]*4, 0, 255, 0, 255);
  145.                 pixelRGBA(wavs, i, 255- (unsigned char)buffer[i], 255, 0, 0, 255);
  146.             }
  147.             lineRGBA(wavs, 247, 255, 247, 255-(unsigned char)fftavg, 255, 255, 255, 128);
  148.             lineRGBA(wavs, 248, 255, 248, 255-(unsigned char)fftavg, 255, 255, 255, 128);
  149.             lineRGBA(wavs, 249, 255, 249, 255-(unsigned char)fftavg, 255, 255, 255, 128);
  150.             lineRGBA(wavs, 250, 255, 250, 255-(unsigned char)fftavg, 255, 255, 255, 128);
  151.  
  152.             lineRGBA(wavs, 251, 255, 251, 255-(unsigned char)level/5, 255, 255, 255, 128);
  153.             lineRGBA(wavs, 252, 255, 252, 255-(unsigned char)level/5, 255, 255, 255, 128);
  154.             lineRGBA(wavs, 253, 255, 253, 255-(unsigned char)level/5, 255, 255, 255, 128);
  155.             lineRGBA(wavs, 254, 255, 254, 255-(unsigned char)level/5, 255, 255, 255, 128);
  156.             SDL_BlitSurface(wavs, NULL, screen, NULL);
  157.             SDL_Flip(screen);
  158.             SDL_PollEvent(&event);
  159.             if(event.type == SDL_QUIT)
  160.             {
  161.                 return 0;
  162.             }
  163.             SDL_Delay(20);
  164.             for(int i = 0; i < 4; i++)
  165.             {
  166.                 red = 64 * ( sin( ( ( ( j + 23 * i ) / 92.0f ) *6.28 )                ) + 1 );
  167.                 grn = 64 * ( sin( ( ( ( j + 23 * i ) / 92.0f ) *6.28 ) + ( 6.28 / 3 ) ) + 1 );
  168.                 blu = 64 * ( sin( ( ( ( j + 23 * i ) / 92.0f ) *6.28 ) - ( 6.28 / 3 ) ) + 1 );
  169.  
  170.                 bus1.fanbus_write(red_leds[i], 0x02, red);
  171.                 bus1.fanbus_write(grn_leds[i], 0x02, grn);
  172.                 bus1.fanbus_write(blu_leds[i], 0x02, blu);
  173.  
  174.                 bus1.fanbus_write(0x0C, 0x02, 0x01);
  175.             }
  176.             for(int x = 0; x < 91; x++)
  177.             {
  178.                 for(int y = 0; y < 7; y++)
  179.                 {
  180.                     red = 1.5f * ( sin( ( x / 92.0f ) * 2 * 3.14f ) + 1 );
  181.                     grn = 1.5f * ( sin( ( ( x / 92.0f ) * 2 * 3.14f ) - ( 6.28f / 3 ) ) + 1 );
  182.                     blu = 1.5f * ( sin( ( ( x / 92.0f ) * 2 * 3.14f ) + ( 6.28f / 3 ) ) + 1 );
  183.  
  184.                     set_led( ( x + j ) % 92, y, red, grn, blu );
  185.                 }
  186.             }
  187.             for(int i = 0; i < 91; i++)
  188.             {
  189.                 for(int k = 0; k < 7; k++)
  190.                 {
  191.                     if( charfft[(int)(i*2.1+1)] > (255/(15 + (i*0.8))) * (7-k) )
  192.                     {
  193.                         set_led( i, k, 0x07, 0x07, 0x07);
  194.                     }
  195.                 }
  196.             }
  197.             update_keyboard();
  198.             usleep(5000);
  199.         }
  200.     }
  201.     return 0;
  202. }
  203.  
  204.  
  205. static void set_led( int x, int y, int r, int g, int b )
  206. {
  207.     int led = led_matrix[y][x];
  208.  
  209.     if(led >= 144)
  210.     {
  211.         return;
  212.     }
  213.  
  214.     if( r > 7 ) r = 7;
  215.     if( g > 7 ) g = 7;
  216.     if( b > 7 ) b = 7;
  217.  
  218.     r = 7 - r;
  219.     g = 7 - g;
  220.     b = 7 - b;
  221.  
  222.     red_val[led] = r;
  223.     grn_val[led] = g;
  224.     blu_val[led] = b;
  225. }
  226.  
  227.  
  228. static int init_keyboard()
  229. {
  230.     int bytes_written = 0;
  231.     int status = 0;
  232.  
  233.     printf("Searching for Corsair K70 RGB keyboard...\n");
  234.  
  235.     dev = find_device(0x1B1C, 0x1B13);
  236.  
  237.     if(dev == NULL)
  238.     {
  239.         printf("Corsair K70 RGB keyboard not detected :(\n");
  240.         return 1;
  241.     }
  242.     else
  243.     {
  244.         printf("Corsair K70 RGB keyboard detected successfully :)\n");
  245.     }
  246.  
  247.     handle = usb_open(dev);
  248.  
  249.     if(handle == NULL)
  250.     {
  251.         printf("USB device handle did not open :(\n");
  252.         return 1;
  253.     }
  254.     else
  255.     {
  256.         printf("USB device handle opened successfully :)\n");
  257.     }
  258.  
  259.     status = usb_claim_interface(handle, 3);
  260.  
  261.     status = usb_detach_kernel_driver_np(handle, 3);
  262.  
  263.     if(status == 0)
  264.     {
  265.         printf("USB interface claimed successfully :)\n");
  266.     }
  267.     else
  268.     {
  269.         printf("USB interface claim failed with error %d :(\n", status);
  270.         return 1;
  271.     }
  272.  
  273.     // Construct XY lookup table
  274.     unsigned char *keys = position_map;
  275.     float *sizes = size_map;
  276.     for (int y = 0; y < 7; y++)
  277.     {
  278.         unsigned char key;
  279.         int size = 0;
  280.  
  281.         for (int x = 0; x < 92; x++)
  282.         {
  283.             if (size == 0)
  284.             {
  285.                 float sizef = *sizes++;
  286.                 if (sizef < 0)
  287.                 {
  288.                     size = -sizef * 4;
  289.                     key = 255;
  290.                 }
  291.                 else
  292.                 {
  293.                     key = *keys++;
  294.                     size = sizef * 4;
  295.                 }
  296.             }
  297.  
  298.             led_matrix[y][x] = key;
  299.             size--;
  300.         }
  301.  
  302.         if (*keys++ != 255 || *sizes++ != 0)
  303.         {
  304.             printf("Bad line %d\n", y);
  305.             return 1;
  306.         }
  307.     }
  308. }
  309.  
  310.  
  311. static void update_keyboard()
  312. {
  313.     // Perform USB control message to keyboard
  314.     //
  315.     // Request Type:  0x21
  316.     // Request:       0x09
  317.     // Value          0x0300
  318.     // Index:         0x03
  319.     // Size:          64
  320.  
  321.     data_pkt[0][0] = 0x7F;
  322.     data_pkt[0][1] = 0x01;
  323.     data_pkt[0][2] = 0x3C;
  324.  
  325.     data_pkt[1][0] = 0x7F;
  326.     data_pkt[1][1] = 0x02;
  327.     data_pkt[1][2] = 0x3C;
  328.  
  329.     data_pkt[2][0] = 0x7F;
  330.     data_pkt[2][1] = 0x03;
  331.     data_pkt[2][2] = 0x3C;
  332.  
  333.     data_pkt[3][0] = 0x7F;
  334.     data_pkt[3][1] = 0x04;
  335.     data_pkt[3][2] = 0x24;
  336.  
  337.         data_pkt[4][0] = 0x07;
  338.         data_pkt[4][1] = 0x27;
  339.         data_pkt[4][4] = 0xD8;
  340.  
  341.     for(int i = 0; i < 60; i++)
  342.     {
  343.         data_pkt[0][i+4] = red_val[i*2+1] << 4 | red_val[i*2];
  344.     }
  345.  
  346.     for(int i = 0; i < 12; i++)
  347.     {
  348.         data_pkt[1][i+4] = red_val[i*2+121] << 4 | red_val[i*2+120];
  349.     }
  350.  
  351.     for(int i = 0; i < 48; i++)
  352.     {
  353.         data_pkt[1][i+16] = grn_val[i*2+1] << 4 | grn_val[i*2];
  354.     }
  355.  
  356.     for(int i = 0; i < 24; i++)
  357.     {
  358.         data_pkt[2][i+4] = grn_val[i*2+97] << 4 | grn_val[i*2+96];
  359.     }
  360.  
  361.     for(int i = 0; i < 36; i++)
  362.     {
  363.         data_pkt[2][i+28] = blu_val[i*2+1] << 4 | blu_val[i*2];
  364.     }
  365.  
  366.     for(int i = 0; i < 36; i++)
  367.     {
  368.         data_pkt[3][i+4] = blu_val[i*2+73] << 4 | blu_val[i*2+72];
  369.     }
  370.  
  371.     usb_control_msg(handle, 0x21, 0x09, 0x0300, 0x03, data_pkt[0], 64, 1000);
  372.     usb_control_msg(handle, 0x21, 0x09, 0x0300, 0x03, data_pkt[1], 64, 1000);
  373.     usb_control_msg(handle, 0x21, 0x09, 0x0300, 0x03, data_pkt[2], 64, 1000);
  374.     usb_control_msg(handle, 0x21, 0x09, 0x0300, 0x03, data_pkt[3], 64, 1000);
  375.     usb_control_msg(handle, 0x21, 0x09, 0x0300, 0x03, data_pkt[4], 64, 1000);
  376. }
  377.  
  378.  
  379. static struct usb_device *find_device(uint16_t vendor, uint16_t product)
  380. {
  381.     struct usb_bus *bus;
  382.     struct usb_device *dev;
  383.     struct usb_bus *busses;
  384.  
  385.     usb_init();
  386.     usb_find_busses();
  387.     usb_find_devices();
  388.  
  389.     busses = usb_get_busses();
  390.  
  391.     for(bus = busses; bus; bus = bus->next)
  392.     {
  393.         for(dev = bus->devices; dev; dev = dev->next)
  394.         {
  395.             if((dev->descriptor.idVendor == vendor) && (dev->descriptor.idProduct == product))
  396.             {
  397.                 return dev;
  398.             }
  399.         }
  400.     }
  401.  
  402.     return NULL;
  403. }
RAW Paste Data
Top