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
Image:BlinkenPlugin.gif Image:Blinken_XMMS_GUI.png
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

download source


Blinken_xmms has been viewed 818 times.

Personal tools