Blinken xmms

From S23Wiki
Jump to: navigation, search

This page is obsolete. The new Version is here: Blinken_XMMS


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
BlinkenPlugin.gif Blinken XMMS GUI.png
Erstellt mit blm2gif
(Graustufen werden leider nicht konvertiert),

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 !


Blinken_XMMS.c

<highlightSyntax language="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`
  • /
  1. include <stdio.h>
  2. include <stdlib.h>
  3. include <unistd.h>
  4. include <string.h>
  5. include <math.h>
  6. include <sys/time.h>
  7. include <sys/types.h>
  8. include <sys/socket.h>
  9. include <netinet/in.h>
  10. include <arpa/inet.h>
  11. include <xmms/plugin.h>
  12. include <xmms/configfile.h>
  1. include "./configure.c"
  1. define NUM_BANDS 18
  2. define WIDTH 18
  3. define HEIGHT 8
  4. define FRAMEDURATION 40000
  1. 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;

}

</highlightSyntax>


blinken_xmms.h

<highlightSyntax language="c">

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;

</highlightSyntax>


configure.h

<highlightSyntax language="c">

  1. include <gtk/gtk.h>
  1. 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); }


</highlightSyntax>

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.


Links

download source


Blinken_xmms has been viewed <counter>page=Blinken_xmms&namespace=0</counter> times.