Blinken xmms
From S23Wiki
This page is obsolete. The new Version is here: Blinken_XMMS
Contents |
[edit] blinken_xmms
Das blinken_xmms ist ein Spectrum-Analyser-Plugin für den Multimedia Player Xmms. Es sendet UDP-Pakete an eine konfigurierbare IP Adresse im EBLP - extended Blinkenlights protocol mit 8x18 Pixeln. Die Ausgabe kann z.B. mit lldrv auf ein BlinkenLEDsPro umgeleitet werden.
| Blinkt zu D&B Musik | Konfigurations GUI |
|---|---|
|
|
| Erstellt mit blm2gif | |
| (Graustufen werden leider nicht konvertiert), |
[edit] Quellcode
Den Quellcode für das XMMS-Plugin habe ich mit Hilfe von Workshop: Vis-Plugins in XMMS und XMMS Plugin tutorial at nobugs.org erstellen können. Desweiteren waren Informationen zum EBLP - extended Blinkenlights protocol sehr nützlich. Der "Rechen-Kern" für die Visualisierung entspricht dem des spectrum Plugins.
Jetzt mit Graustufen und Konfig-GUI!
Blinken_XMMS.c ! Beim Speichern --> Dateiname: Blinken_XMMS.c !
blinken_xmms.h ! Beim Speichern --> Dateiname: blinken_xmms.h !
configure.h ! Beim Speichern --> Dateiname: configure.c !
[edit] Blinken_XMMS.c
/* Blinken_XMMS : for XMMS - Cross-platform multimedia player
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License forore details.
*
* You should have received a copy of the GNU General Public License
* along with XMMS.
*/
/* Compile:
* gcc -Wall --shared `xmms-config --cflags` -o Blinken_XMMS.so Blinken_XMMS.c
* Install:
* install Blinken_XMMS.so `xmms-config --visualization-plugin-dir`
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <xmms/plugin.h>
#include <xmms/configfile.h>
#include "./configure.c"
#define NUM_BANDS 18
#define WIDTH 18
#define HEIGHT 8
#define FRAMEDURATION 40000
#define MSG {0xFE,0xED,0xBE,0xEF,0x00,0x00,0x00,0x00,0x00,0x012,0x00,0x08,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
static int sock;
static unsigned char msg[156]=MSG;
static unsigned char scalmsg[10] = {0x11, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xAA, 0xCC, 0x00};
BlinkenXmmsConfig blinken_cfg;
static gdouble scale;
static gint16 bar_heights[NUM_BANDS];
void blinken_init();
void blinken_playback_start();
void blinken_playback_stop();
void blinken_render_freq(gint16 data[1][256]);
static long int timer;
struct timeval tp;
VisPlugin g_blinken_plugin =
{
NULL, /* handle */
NULL, /* filename */
0, /* session id */
"Blinken_XMMS", /* description */
0, /* PCM Channels */
1, /* Freq. Channels */
/* Callbacks ... */
blinken_init, /* init */
blinken_cleanup, /* cleanup */
NULL, /* about-dialog */
blinken_configure, /* configure-dialog */
NULL, /* disable-plugin */
blinken_playback_start, /* playback-start */
blinken_playback_stop, /* playback-top */
NULL, /* render-pcm */
blinken_render_freq /* render-freq */
};
VisPlugin *get_vplugin_info(void)
{
return( & g_blinken_plugin);
}
/* Read current settings from the xmms config file */
void blinken_read_config(void)
{
ConfigFile *cfg;
gchar *filename;
filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
cfg = xmms_cfg_open_file(filename);
if (cfg)
{
xmms_cfg_read_string(cfg, "Blinken_XMMS", "blinkenip", &blinken_cfg.ip);
xmms_cfg_read_int(cfg, "Blinken_XMMS", "blinkenport", &blinken_cfg.port);
xmms_cfg_free(cfg);
}
g_free(filename);
if (blinken_cfg.ip==NULL) {
blinken_cfg.ip = g_strdup("127.0.0.1");
blinken_cfg.port = 2323;
}
}
/* Save current settings to the xmms config file */
void blinken_save_config(void)
{
ConfigFile *cfgfile;
gchar *filename;
filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
cfgfile = xmms_cfg_open_file(filename);
if (!cfgfile)
cfgfile = xmms_cfg_new();
xmms_cfg_write_string(cfgfile, "Blinken_XMMS", "blinkenip", blinken_cfg.ip);
xmms_cfg_write_int(cfgfile, "Blinken_XMMS", "blinkenport", blinken_cfg.port);
xmms_cfg_write_file(cfgfile, filename);
xmms_cfg_free(cfgfile);
g_free(filename);
}
void blinken_udp_init(void)
{
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("couldn't create socket");
blinken_cleanup();
exit(1);
}
struct sockaddr_in dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(blinken_cfg.port);
dest_addr.sin_addr.s_addr = inet_addr(blinken_cfg.ip);
if (connect(sock, (struct sockaddr*) &dest_addr, sizeof(dest_addr)) == -1)
{
printf("couldn't connect to %s:%d\n",blinken_cfg.ip,blinken_cfg.port);
blinken_configure();
blinken_cleanup();
exit(2);
}
//printf("connected to %s:%d\n",blinken_cfg.ip,blinken_cfg.port);
send(sock, msg, 156, 0);
}
void blinken_init()
{
if (blinken_cfg.ip==NULL)
blinken_read_config();
blinken_udp_init();
scale = (HEIGHT + 1)/ log(256);
}
void blinken_cleanup()
{
close(sock);
}
void blinken_playback_start()
{
gettimeofday(&tp,NULL);
timer=tp.tv_usec;
//printf( "playback_start\n");
}
void blinken_playback_stop()
{
unsigned char msg[156]=MSG;
send(sock, msg, 156, 0);
}
void blinken_render_freq( gint16 data[1][256])
{
gettimeofday(&tp,NULL);
if ((tp.tv_usec-timer)<FRAMEDURATION && (tp.tv_usec-timer)>0)
return;
//printf( "playback_run %ld\n",tp.tv_usec-timer);
timer=tp.tv_usec;
int result,zeile,spalte;
int i,j,c;
gint y;
gint xscale[NUM_BANDS] = {0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54, 74, 85, 101, 137, 140, 150};
for(i = 0; i < NUM_BANDS; i++)
{
for(c = xscale[i], y = 0; c < xscale[i + 1]; c++)
{
if(data[0][c] > y)
{
y = data[0][c];
}
}
y >>= 7;
if(y != 0)
{
y = (gint)(log(y) * scale);
if(y > HEIGHT+1)
{
y = HEIGHT+1;
}
}
bar_heights[i] = -y+9;
}
spalte = 0;
zeile = 0;
for(i=12;i<=155;i++)
{
j = i-12;
zeile = j/18;
spalte = j%18;
if((bar_heights[spalte])==zeile+1)
{
msg[i]=0xFF;
}
else if((bar_heights[spalte])<zeile+1)
{
msg[i]=scalmsg[bar_heights[spalte]];
}
else
{
msg[i]=0x00;
}
}
result = send(sock, msg, 156, 0);
return;
}
[edit] blinken_xmms.h
extern void blinken_udp_init();
extern void blinken_cleanup();
extern void blinken_configure(void);
extern void blinken_read_config(void);
extern void blinken_save_config(void);
typedef struct
{
gchar *ip;
gint port;
} BlinkenXmmsConfig;
extern BlinkenXmmsConfig blinken_cfg;
[edit] configure.h
#include <gtk/gtk.h>
#include "blinken_xmms.h"
static GtkWidget *configure_win = NULL;
static GtkWidget *vbox, *options_frame, *options_vbox;
static GtkWidget *bbox, *ok, *cancel;
static GtkWidget *dev_ip, *dev_port;
static void configure_ok(GtkWidget *w, gpointer data)
{
blinken_cfg.ip = g_strdup(gtk_entry_get_text(GTK_ENTRY(dev_ip)));
blinken_cfg.port = atoi(gtk_entry_get_text(GTK_ENTRY(dev_port)));
printf("ip: %s\nport: %d\n",blinken_cfg.ip,blinken_cfg.port);
blinken_cleanup();
blinken_udp_init();
blinken_save_config();
gtk_widget_destroy(configure_win);
}
void blinken_configure (void)
{
GtkWidget *frame, *table, *label, *label_port;
if(configure_win)
return;
blinken_read_config();
configure_win = gtk_window_new(GTK_WINDOW_DIALOG);
gtk_container_set_border_width(GTK_CONTAINER(configure_win), 10);
gtk_window_set_title(GTK_WINDOW(configure_win), ("Blinken XMMS configuration"));
gtk_window_set_policy(GTK_WINDOW(configure_win), FALSE, FALSE, FALSE);
gtk_window_set_position(GTK_WINDOW(configure_win), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(configure_win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed),
&configure_win);
vbox = gtk_vbox_new(FALSE, 5);
options_frame = gtk_frame_new(("Options:"));
gtk_container_set_border_width(GTK_CONTAINER(options_frame), 5);
options_vbox = gtk_vbox_new(FALSE, 5);
gtk_container_set_border_width(GTK_CONTAINER(options_vbox), 5);
frame = gtk_frame_new(("Connection"));
gtk_box_pack_start(GTK_BOX(options_vbox), frame, FALSE, FALSE, 0);
table = gtk_table_new(2, 1, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
label = gtk_label_new(("IP Adr.:"));
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
gtk_widget_show(label);
dev_ip = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(dev_ip), blinken_cfg.ip);
gtk_table_attach_defaults(GTK_TABLE(table), dev_ip, 1, 2, 0, 1);
gtk_widget_show(dev_ip);
label_port = gtk_label_new(("Port:"));
gtk_misc_set_alignment(GTK_MISC(label_port), 1.0, 0.5);
gtk_table_attach_defaults(GTK_TABLE(table), label_port, 0, 1, 1, 2);
gtk_widget_show(label_port);
dev_port = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(dev_port), g_strdup_printf("%d", blinken_cfg.port));
gtk_table_attach_defaults(GTK_TABLE(table), dev_port, 1, 2, 1, 2);
gtk_widget_show(dev_port);
gtk_widget_show(table);
gtk_widget_show(frame);
gtk_container_add(GTK_CONTAINER(options_frame), options_vbox);
gtk_widget_show(options_vbox);
gtk_box_pack_start(GTK_BOX(vbox), options_frame, TRUE, TRUE, 0);
gtk_widget_show(options_frame);
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
ok = gtk_button_new_with_label(("OK"));
gtk_signal_connect(GTK_OBJECT(ok), "clicked", GTK_SIGNAL_FUNC(configure_ok), NULL);
GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
gtk_widget_show(ok);
cancel = gtk_button_new_with_label(("Cancel"));
gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(configure_win));
GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
gtk_widget_show(cancel);
gtk_widget_show(bbox);
gtk_container_add(GTK_CONTAINER(configure_win), vbox);
gtk_widget_show(vbox);
gtk_widget_show(configure_win);
gtk_widget_grab_default(ok);
}
[edit] Installation
gcc -Wall --shared `xmms-config --cflags` -o Blinken_XMMS.so Blinken_XMMS.c
install Blinken_XMMS.so `xmms-config --visualization-plugin-dir`
Evtl. ist das dev. Paket von xmms erforderlich.
Nun kann man mit einem Rechtsklick auf das XMMS-Fenster im Menü: Visualisierung-->Visualisierungs-Plugins
Blinken_XMMS
auswählen. Mit einem Klick auf den Konfigurationsknopf ist es möglich die Ziel- IP Adresse und Port einzutragen. Um den UDP-Stream umzuleiten kann z.B
./BlinkenOutput -l 2323 -d /dev/lldrv
benutzt werden.
[edit] Links
Blinken_xmms has been viewed 818 times.



