// LCD Raptor 0.3 -- XMMS Visualization Plugin // // Rewritten by Mauricio Gomes // http://www.retechnologies.org // // original LCDxmms by kuro // with mods by fragment // // ported to audacious // with further mods by kripton 04/04/2006 #include #include #include #include #include #include #include #include #include #include "sockets.h" #define VERSION "0.5" #define TIME_UNIT 125000 #define NUM_BANDS 16 // This is, how many times the loop has to be run // before sending data to LCDd // 1 => send every loop update t LCDd (you WILL get disconnected) // 2 => send every 2nd loop // 10 => send every 10th loop #define LOOPS 2 static gint16 bar_heights[NUM_BANDS]; int sock; int broken = 0; int lcd_width; int lcd_height; int lcd_cellwidth; int lcd_cellheight; int max_width; int playlist_pos; int loopcounter; static void lcd_init(void); static void lcd_cleanup(void); static void lcd_playback_start(void); static void lcd_playback_stop(void); static void lcd_about(void); static void lcd_render_freq(gint16 data[2][256]); char *get_token(char *buf); VisPlugin lcd_vp = { NULL, NULL, 0, NULL, /* Description */ 0, 1, lcd_init, /* init */ lcd_cleanup, /* cleanup */ lcd_about, /* about */ NULL, /* configure */ NULL, /* disable_plugin */ lcd_playback_start, /* playback_start */ lcd_playback_stop, /* playback_stop */ NULL, /* render_pcm */ lcd_render_freq /* render_freq */ }; VisPlugin *get_vplugin_info(void) { lcd_vp.description = g_strdup_printf("LCD Raptor vis-plugin v%s", VERSION); return &lcd_vp; } static void lcd_about(void) { GtkWidget *dialog; dialog = xmms_show_message("About LCD Raptor", "LCD Raptor vis-plugin v" VERSION "\nPuts song info and a bar analyzer\n" "on a 20x4 LCD via LCDproc.\n\n" "------------------------------\n\n" "Rewritten by Mauricio Gomes \n" "http://www.retechnologies.org\n\n" "originally by kuro \n" "with mods by fragment \n\n" "ported to audacious\n" "with further mods by kripton ", "close", FALSE, NULL, NULL); gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog); } static void lcd_init(void) { int len; int count = 0; char buf[8192]; char *token = NULL; char arg[20]; sock = sock_connect("localhost", LCDPORT); if(sock<=0) { printf("Error connecting to localhost on port LCDPORT.\n"); broken = 1; return; } sock_send_string(sock, "hello\n"); do { usleep(TIME_UNIT); len = sock_recv(sock, buf, 8000); count++; } while (len <= 0 && count < 50); if(len <= 0) { printf("Couldn't communicate with server!\n"); broken = 1; return; } buf[len] = '\0'; //add a null char cause sock_recv doesnt token = strstr(buf, "wid"); //speed things up a little =) token = index(token, ' ') + 1; strncpy(arg, token, index(token, ' ') - token); lcd_width = atoi(arg); bzero(arg, strlen(arg)); token = index(token, ' ') + 1; token = index(token, ' ') + 1; strncpy(arg, token, index(token, ' ') - token); lcd_height = atoi(arg); bzero(arg, strlen(arg)); token = index(token, ' ') + 1; token = index(token, ' ') + 1; strncpy(arg, token, index(token, ' ') - token); lcd_cellwidth = atoi(arg); bzero(arg, strlen(arg)); token = index(token, ' ') + 1; token = index(token, ' ') + 1; strncpy(arg, token, index(token, '\0') - token); lcd_cellheight = atoi(arg); bzero(arg, strlen(arg)); max_width = lcd_cellwidth * lcd_width; sock_send_string(sock, "client_set name {LCDraptor}\n"); } static void lcd_cleanup(void) { sock_close(sock); } static void lcd_playback_start(void) { gint i; char cmd[240]; int playlist_pos; char *song_title; if(broken) return; playlist_pos = xmms_remote_get_playlist_pos(0); song_title = xmms_remote_get_playlist_title(0, playlist_pos); sprintf(cmd, "widget_set xmms song {%s}\n", song_title); sock_send_string(sock, "screen_add xmms\n"); sock_send_string(sock, "screen_set xmms name {LCDraptor}\n"); sock_send_string(sock, "screen_set xmms heartbeat on\n"); sock_send_string(sock, "screen_set xmms backlight on\n"); sock_send_string(sock, "widget_add xmms tclock string\n"); sock_send_string(sock, "widget_set xmms tclock 1 2 {00/00 00:00/00:00}\n"); sock_send_string(sock, "widget_add xmms song title\n"); sock_send_string(sock, cmd); for(i = 1; i <= NUM_BANDS; i++) { snprintf(cmd, 80, "widget_add xmms bar%i vbar\n", i); sock_send_string(sock,cmd); snprintf(cmd, 80, "widget_set xmms bar%i %i 4 1\n",i,i+2); sock_send_string(sock,cmd); } loopcounter = 0; } static void lcd_playback_stop(void) { char cmd[80]; gint i; if(broken) return; sock_send_string(sock, "widget_del xmms song\n"); sock_send_string(sock, "widget_del xmms tclock\n"); for(i = 1; i <= NUM_BANDS; i++) { sprintf(cmd, "widget_del xmms bar%i\n",i); sock_send_string(sock, cmd); } sock_send_string(sock, "screen_del xmms\n"); } static void lcd_render_freq(gint16 data[2][256]) { if (loopcounter == LOOPS) { char buf[8192]; char cmd[240]; char *song_title; int len, pllength; int i, j, y, time_code, time_min, time_sec; int tracklength, tl_min, tl_sec; int xscale[] = {0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54, 74, 101, 137, 187, 255}; if(broken) return; len = sock_recv(sock, buf, 8000); //dont want the pipes to clog if(xmms_remote_get_playlist_pos(0) != playlist_pos) { playlist_pos = xmms_remote_get_playlist_pos(0); song_title = xmms_remote_get_playlist_title(0, playlist_pos); sprintf(cmd, "widget_set xmms song {%s}\n", song_title); sock_send_string(sock, cmd); } for(i = 0; i < NUM_BANDS; i++) { for(j=xscale[i], y=0; j < xscale[i+1]; j++) { if(data[0][j] > y) y = data[0][j]; } y >>= 7; if(y != 0) { y = (gint)(log(y) * (32/log(256))); if(y > 16) y = 16; } if(y > bar_heights[i]) bar_heights[i] = y; else if(bar_heights[i] > 5) bar_heights[i] -= 5; else bar_heights[i] = 1; } for(i = 0; i < NUM_BANDS; i++) { sprintf(cmd, "widget_set xmms bar%i %i 4 %i\n",i+1,i+3,bar_heights[i]); sock_send_string(sock, cmd); } time_code = xmms_remote_get_output_time(0) / 1000; time_min = time_code / 60; time_sec = time_code % 60; pllength = xmms_remote_get_playlist_length(0); tracklength = xmms_remote_get_playlist_time(0, playlist_pos) / 1000; tl_min = tracklength / 60; tl_sec = tracklength % 60; sprintf(cmd, "widget_set xmms tclock 1 2 {%.2d/%.2d %.2d:%.2d/%.2d:%.2d}\n", playlist_pos+1, pllength, time_min, time_sec, tl_min, tl_sec); sock_send_string(sock, cmd); loopcounter = 0; } else { loopcounter++; } }