Decoupled from Audacious

This commit is contained in:
Duilio Protti 2016-06-29 23:34:31 -03:00
parent b02c419143
commit 9125da6100
9 changed files with 326 additions and 206 deletions

View File

@ -1,7 +1,7 @@
## Process this file with autoconf to produce a configure script. ## Process this file with autoconf to produce a configure script.
AC_PREREQ(2.65) AC_PREREQ(2.65)
AC_INIT([Infinity plugin],[0.9.0alpha],[https://github.com/dprotti/infinity-plugin/issues],[infinity-plugin-4-audacious],[https://dprotti.github.io/infinity-plugin]) AC_INIT([Infinity plugin],[0.9.0-dev],[https://github.com/dprotti/infinity-plugin/issues],[infinity-plugin],[https://dprotti.github.io/infinity-plugin])
AC_CANONICAL_HOST AC_CANONICAL_HOST
AC_CANONICAL_TARGET AC_CANONICAL_TARGET
@ -189,6 +189,5 @@ Compiler : ${CC}
CFLAGS : ${INF_CFLAGS_EXTRA} ${CFLAGS} CFLAGS : ${INF_CFLAGS_EXTRA} ${CFLAGS}
CXXFLAGS : ${CXXFLAGS} CXXFLAGS : ${CXXFLAGS}
Debug enabled : ${debug} Debug enabled : ${debug}
MMX Extensions support : ${mmx}
" "

View File

@ -15,8 +15,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)
libinfinite_la_LDFLAGS = ${CXX} libinfinite_la_LDFLAGS = ${CXX}
libinfinite_la_LIBADD = @AUDACIOUS_LIBS@ @SDL_LIBS@ @GTK_LIBS@ @GLIB_LIBS@ libinfinite_la_LIBADD = @AUDACIOUS_LIBS@ @SDL_LIBS@ @GTK_LIBS@ @GLIB_LIBS@
libinfinite_la_SOURCES = \ libinfinite_la_SOURCES = \
main.cc \ audacious.cc \
renderer.cc renderer.h\ infinity.c infinity.h\
compute.c compute.h \ compute.c compute.h \
display.c display.h \ display.c display.h \
effects.c effects.h\ effects.c effects.h\

View File

@ -14,17 +14,21 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <string.h> #include <string.h>
#include <libaudcore/drct.h>
#include <libaudcore/playlist.h>
#include <libaudcore/plugin.h> #include <libaudcore/plugin.h>
#include <libaudcore/plugins.h>
#include <libaudcore/preferences.h> #include <libaudcore/preferences.h>
#include <libaudcore/runtime.h> #include <libaudcore/runtime.h>
#include <glib/gi18n.h>
extern "C" { extern "C" {
#include "config.h" #include "config.h"
#include "renderer.h" #include "infinity.h"
#include "types.h" #include "types.h"
} }
#define CFGID "infinity"
static const char about_text[] = static const char about_text[] =
"Infinity " PACKAGE_VERSION "\n\n" "Infinity " PACKAGE_VERSION "\n\n"
"Julien Carme, Duilio Protti\n\n" "Julien Carme, Duilio Protti\n\n"
@ -73,6 +77,113 @@ private:
EXPORT InfinityPlugin aud_plugin_instance; EXPORT InfinityPlugin aud_plugin_instance;
static gint32 get_width() {
return aud_get_int(CFGID, "width");
}
static void set_width(gint32 width) {
aud_set_int(CFGID, "width", width);
}
static gint32 get_height() {
return aud_get_int(CFGID, "height");
}
static void set_height(gint32 height) {
aud_set_int(CFGID, "height", height);
}
static gint32 get_scale() {
return aud_get_int(CFGID, "scale_factor");
}
static gint32 get_effect_interval() {
return aud_get_int(CFGID, "effect_time");
}
static gint32 get_color_interval() {
return aud_get_int(CFGID, "palette_time");
}
static gboolean must_show_title() {
return aud_get_bool(CFGID, "show_title");
}
static gint32 get_max_fps() {
return aud_get_int(CFGID, "max_fps");
}
static InfParameters params;
static void init_params() {
params.get_width = get_width;
params.set_width = set_width;
params.get_height = get_height;
params.set_height = set_height;
params.get_scale = get_scale;
params.get_effect_interval = get_effect_interval;
params.get_color_interval = get_color_interval;
params.must_show_title = must_show_title;
params.get_max_fps = get_max_fps;
};
static gboolean is_playing() {
return aud_drct_get_playing() && aud_drct_get_ready();
}
static gchar* get_title() {
String title = aud_playlist_get_title(aud_playlist_get_playing());
return (gchar*) title.to_raw();
}
static void play() {
aud_drct_play();
}
static void pause() {
aud_drct_pause();
}
static void stop() {
aud_drct_stop();
}
static void previous() {
aud_drct_pl_prev();
}
static void next() {
aud_drct_pl_next();
}
static void seek(gint32 usecs) {
aud_drct_seek(aud_drct_get_time() + usecs);
}
static void adjust_volume(gint delta) {
gint volume = aud_drct_get_volume_main();
g_message("Increasing volume to %d", volume + 5);
aud_drct_set_volume_main(volume + delta);
}
static void disable_plugin() {
PluginHandle * plugin = aud_plugin_lookup_basename("libinfinite");
aud_plugin_enable(plugin, false);
}
static Player player = {
.is_playing = is_playing,
.get_title = get_title,
.play = play,
.pause = pause,
.stop = stop,
.previous = previous,
.next = next,
.seek = seek,
.adjust_volume = adjust_volume,
.disable_plugin = disable_plugin
};
bool InfinityPlugin::init(void) bool InfinityPlugin::init(void)
{ {
g_message("Infinity commands:\n" g_message("Infinity commands:\n"
@ -89,7 +200,9 @@ bool InfinityPlugin::init(void)
"- F11:\t\tscreenshot.\n" "- F11:\t\tscreenshot.\n"
"- F12:\t\tchange palette."); "- F12:\t\tchange palette.");
load_settings(); load_settings();
renderer_init(); init_params();
infinity_init(&params, &player);
return TRUE; return TRUE;
} }
@ -101,11 +214,11 @@ void InfinityPlugin::clear ()
void InfinityPlugin::cleanup(void) void InfinityPlugin::cleanup(void)
{ {
g_message("Infinity: cleanup()"); g_message("Infinity: cleanup()");
renderer_finish(); infinity_finish();
} }
void InfinityPlugin::render_multi_pcm (const float * pcm, int channels) { void InfinityPlugin::render_multi_pcm (const float * pcm, int channels) {
renderer_render_multi_pcm(pcm, channels); infinity_render_multi_pcm(pcm, channels);
} }
static const char * const defaults[] = { static const char * const defaults[] = {

View File

@ -31,7 +31,7 @@ typedef struct t_complex {
gfloat x, y; gfloat x, y;
} t_complex; } t_complex;
static t_screen_parameters scr_par; static gint32 width, height, scale;
static byte *surface1; static byte *surface1;
static byte *surface2; static byte *surface2;
@ -45,15 +45,15 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
gfloat speed; gfloat speed;
gfloat co, si; gfloat co, si;
a.x -= scr_par.width / 2; a.x -= width / 2;
a.y -= scr_par.height / 2; a.y -= height / 2;
switch (n) { switch (n) {
case 0: case 0:
an = 0.025 * (p1 - 2) + 0.002; an = 0.025 * (p1 - 2) + 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.25; circle_size = height * 0.25;
speed = (gfloat)2000 + p2 * 500; speed = (gfloat)2000 + p2 * 500;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -65,7 +65,7 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
an = 0.015 * (p1 - 2) + 0.002; an = 0.015 * (p1 - 2) + 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.45; circle_size = height * 0.45;
speed = (gfloat)4000 + p2 * 1000; speed = (gfloat)4000 + p2 * 1000;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -77,7 +77,7 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
an = 0.002; an = 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.25; circle_size = height * 0.25;
speed = (gfloat)400 + p2 * 100; speed = (gfloat)400 + p2 * 100;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -89,7 +89,7 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
an = (sin(sqrt(a.x * a.x + a.y * a.y) / 20) / 20) + 0.002; an = (sin(sqrt(a.x * a.x + a.y * a.y) / 20) / 20) + 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.25; circle_size = height * 0.25;
speed = (gfloat)4000; speed = (gfloat)4000;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -101,7 +101,7 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
an = 0.002; an = 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.25; circle_size = height * 0.25;
speed = sin(sqrt(a.x * a.x + a.y * a.y) / 5) * 3000 + 4000; speed = sin(sqrt(a.x * a.x + a.y * a.y) / 5) * 3000 + 4000;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -117,7 +117,7 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
an = 0.002; an = 0.002;
co = cos(an); co = cos(an);
si = sin(an); si = sin(an);
circle_size = scr_par.height * 0.25; circle_size = height * 0.25;
fact = 1 + cos(atan(a.x / (a.y + 0.00001)) * 6) * 0.02; fact = 1 + cos(atan(a.x / (a.y + 0.00001)) * 6) * 0.02;
b.x = (co * a.x - si * a.y); b.x = (co * a.x - si * a.y);
b.y = (si * a.x + co * a.y); b.y = (si * a.x + co * a.y);
@ -128,16 +128,16 @@ static inline t_complex fct(t_complex a, guint32 n, gint32 p1, gint32 p2) /* p
b.x = (gfloat)0.0; b.x = (gfloat)0.0;
b.y = (gfloat)0.0; b.y = (gfloat)0.0;
} }
b.x += scr_par.width / 2; b.x += width / 2;
b.y += scr_par.height / 2; b.y += height / 2;
if (b.x < 0.0) if (b.x < 0.0)
b.x = 0.0; b.x = 0.0;
if (b.y < 0.0) if (b.y < 0.0)
b.y = 0.0; b.y = 0.0;
if (b.x > (gfloat)scr_par.width - 1) if (b.x > (gfloat)width - 1)
b.x = (gfloat)scr_par.width - 1; b.x = (gfloat)width - 1;
if (b.y > (gfloat)scr_par.height - 1) if (b.y > (gfloat)height - 1)
b.y = (gfloat)scr_par.height - 1; b.y = (gfloat)height - 1;
return b; return b;
} }
@ -184,24 +184,24 @@ static inline void compute_generate_sector(guint32 g, guint32 f, guint32 p1, gui
} }
} }
void compute_init(gint32 width, gint32 height, gint32 scale) void compute_init(gint32 _width, gint32 _height, gint32 _scale)
{ {
scr_par.width = width; width = _width;
scr_par.height = height; height = _height;
scr_par.scale = scale; scale = _scale;
surface1 = (byte *)g_malloc((gulong)(scr_par.width + 1) * (scr_par.height + 1)); surface1 = (byte *)g_malloc((gulong)(width + 1) * (height + 1));
surface2 = (byte *)g_malloc((gulong)(scr_par.width + 1) * (scr_par.height + 1)); surface2 = (byte *)g_malloc((gulong)(width + 1) * (height + 1));
} }
void compute_resize(gint32 width, gint32 height) void compute_resize(gint32 _width, gint32 _height)
{ {
scr_par.width = width; width = _width;
scr_par.height = height; height = _height;
g_free(surface1); g_free(surface1);
g_free(surface2); g_free(surface2);
surface1 = (byte *)g_malloc((gulong)(scr_par.width + 1) * (scr_par.height + 1)); surface1 = (byte *)g_malloc((gulong)(width + 1) * (height + 1));
surface2 = (byte *)g_malloc((gulong)(scr_par.width + 1) * (scr_par.height + 1)); surface2 = (byte *)g_malloc((gulong)(width + 1) * (height + 1));
} }
vector_field_t *compute_vector_field_new(gint32 width, gint32 height) vector_field_t *compute_vector_field_new(gint32 width, gint32 height)
@ -232,15 +232,15 @@ void compute_quit()
void compute_generate_vector_field(vector_field_t *vector_field) void compute_generate_vector_field(vector_field_t *vector_field)
{ {
guint32 f, i, height; guint32 f, i, _height;
g_return_if_fail(vector_field != NULL); g_return_if_fail(vector_field != NULL);
g_return_if_fail(vector_field->height >= 0); g_return_if_fail(vector_field->height >= 0);
height = (guint32)vector_field->height; _height = (guint32)vector_field->height;
for (f = 0; f < NB_FCT; f++) for (f = 0; f < NB_FCT; f++)
for (i = 0; i < height; i += 10) for (i = 0; i < _height; i += 10)
compute_generate_sector(f, f, 2, 2, i, 10, vector_field); compute_generate_sector(f, f, 2, 2, i, 10, vector_field);
} }

View File

@ -35,7 +35,7 @@ typedef struct sincos {
static gint16 pcm_data[2][512]; static gint16 pcm_data[2][512];
static SDL_mutex *pcm_data_mutex; static SDL_mutex *pcm_data_mutex;
static t_screen_parameters scr_par; static gint32 width, height, scale;
/* Little optimization for cos/sin functions */ /* Little optimization for cos/sin functions */
static sincos_t cosw = { 0, NULL }; static sincos_t cosw = { 0, NULL };
@ -50,11 +50,11 @@ static gint16 current_colors[256];
static byte *surface1; static byte *surface1;
static void init_sdl(gint32 width, gint32 height, gint32 scale) static void init_sdl(gint32 _width, gint32 _height, gint32 _scale)
{ {
if (SDL_Init((Uint32)(SDL_INIT_VIDEO | SDL_INIT_TIMER)) < 0) if (SDL_Init((Uint32)(SDL_INIT_VIDEO | SDL_INIT_TIMER)) < 0)
g_error("Infinity: Couldn't initialize SDL: %s\n", SDL_GetError()); g_error("Infinity: Couldn't initialize SDL: %s\n", SDL_GetError());
screen = SDL_SetVideoMode(width * scale, height * scale, 16, VIDEO_FLAGS); screen = SDL_SetVideoMode(_width * _scale, _height * _scale, 16, VIDEO_FLAGS);
if (screen == NULL) if (screen == NULL)
g_error("Infinity: could not init video mode: %s\n", SDL_GetError()); g_error("Infinity: could not init video mode: %s\n", SDL_GetError());
g_message("Infinity: SDL SetVideoMode() Ok"); g_message("Infinity: SDL SetVideoMode() Ok");
@ -99,12 +99,12 @@ static void display_surface()
} else { } else {
screen_locked = FALSE; screen_locked = FALSE;
} }
if (scr_par.scale > 1) { if (scale > 1) {
for (i = 0; i < scr_par.height; i++) { for (i = 0; i < height; i++) {
pdest = (gint16 *)(screen->pixels + i * screen->pitch * scr_par.scale); pdest = (gint16 *)(screen->pixels + i * screen->pitch * scale);
psrc = surface1 + i * scr_par.width; psrc = surface1 + i * width;
if (scr_par.scale == 2) { if (scale == 2) {
for (j = 1; j < scr_par.width; j++) { for (j = 1; j < width; j++) {
*(pdest++) = current_colors[*psrc++]; *(pdest++) = current_colors[*psrc++];
*(pdest) = *(pdest - 1); *(pdest) = *(pdest - 1);
pdest++; pdest++;
@ -112,7 +112,7 @@ static void display_surface()
memcpy(screen->pixels + i * screen->pitch * 2 + screen->pitch, memcpy(screen->pixels + i * screen->pitch * 2 + screen->pitch,
screen->pixels + i * screen->pitch * 2, screen->pitch); screen->pixels + i * screen->pitch * 2, screen->pitch);
} /* else { } /* else {
* for (j=1;j<scr_par.width;j++) { * for (j=1;j<width;j++) {
*(pdest++)=current_colors[*psrc++]; *(pdest++)=current_colors[*psrc++];
*(pdest++)=*(pdest-1); *(pdest++)=*(pdest-1);
*(pdest++)=*(pdest-1); *(pdest++)=*(pdest-1);
@ -125,9 +125,9 @@ static void display_surface()
} /* for */ } /* for */
} else { } else {
psrc = surface1; psrc = surface1;
for (i = 0; i < scr_par.height; i++) { for (i = 0; i < height; i++) {
pdest = (gint16 *)(screen->pixels + i * screen->pitch); pdest = (gint16 *)(screen->pixels + i * screen->pitch);
for (j = 0; j < scr_par.width; j++) for (j = 0; j < width; j++)
*pdest++ = current_colors[*psrc++]; *pdest++ = current_colors[*psrc++];
} }
} }
@ -139,19 +139,19 @@ static void display_surface()
#define plot1(x, y, c) \ #define plot1(x, y, c) \
\ \
if ((x) > 0 && (x) < scr_par.width - 3 && (y) > 0 && (y) < scr_par.height - 3) \ if ((x) > 0 && (x) < width - 3 && (y) > 0 && (y) < height - 3) \
assign_max(&(surface1)[(x) + (y) * scr_par.width], (c)) \ assign_max(&(surface1)[(x) + (y) * width], (c)) \
\ \
#define plot2(x, y, c) \ #define plot2(x, y, c) \
{ \ { \
gint32 ty; \ gint32 ty; \
if ((x) > 0 && (gint32)(x) < scr_par.width - 3 && (y) > 0 && (gint32)(y) < scr_par.height - 3) { \ if ((x) > 0 && (gint32)(x) < width - 3 && (y) > 0 && (gint32)(y) < height - 3) { \
ty = (gint32)(y) * scr_par.width; \ ty = (gint32)(y) * width; \
assign_max((&(surface1)[(gint32)(x) + ty]), (c)); \ assign_max((&(surface1)[(gint32)(x) + ty]), (c)); \
assign_max((&(surface1)[(gint32)(x) + 1 + ty]), (c)); \ assign_max((&(surface1)[(gint32)(x) + 1 + ty]), (c)); \
assign_max((&(surface1)[(gint32)(x) + ty + scr_par.width]), (c)); \ assign_max((&(surface1)[(gint32)(x) + ty + width]), (c)); \
assign_max((&(surface1)[(gint32)(x) + 1 + ty + scr_par.width]), (c)); \ assign_max((&(surface1)[(gint32)(x) + 1 + ty + width]), (c)); \
} \ } \
} \ } \
@ -208,11 +208,11 @@ static void line(gint32 x1, gint32 y1, gint32 x2, gint32 y2, gint32 c)
} }
} }
void display_init(gint32 width, gint32 height, gint32 scale) void display_init(gint32 _width, gint32 _height, gint32 _scale)
{ {
scr_par.width = width; width = _width;
scr_par.height = height; height = _height;
scr_par.scale = scale; scale = _scale;
pcm_data_mutex = SDL_CreateMutex(); pcm_data_mutex = SDL_CreateMutex();
compute_init(width, height, scale); compute_init(width, height, scale);
@ -234,16 +234,16 @@ void display_quit(void)
SDL_Quit(); SDL_Quit();
} }
void display_resize(gint32 width, gint32 height) void display_resize(gint32 _width, gint32 _height)
{ {
scr_par.width = width; width = _width;
scr_par.height = height; height = _height;
screen = SDL_SetVideoMode(scr_par.width * scr_par.scale, screen = SDL_SetVideoMode(width * scale,
scr_par.height * scr_par.scale, height * scale,
16, VIDEO_FLAGS); 16, VIDEO_FLAGS);
if (screen == NULL) if (screen == NULL)
g_error("Infinity: Couldn't set %dx%d video mode: %s\n", g_error("Infinity: Couldn't set %dx%d video mode: %s\n",
scr_par.width * scr_par.scale, scr_par.height * scr_par.scale, width * scale, height * scale,
SDL_GetError()); SDL_GetError());
compute_vector_field_destroy(vector_field); compute_vector_field_destroy(vector_field);
vector_field = compute_vector_field_new(width, height); vector_field = compute_vector_field_new(width, height);
@ -301,13 +301,13 @@ void spectral(t_effect *current_effect)
gfloat y1, y2; gfloat y1, y2;
const gint32 density_lines = 5; const gint32 density_lines = 5;
const gint32 step = 4; const gint32 step = 4;
const gint32 shift = (current_effect->spectral_shift * scr_par.height) >> 8; const gint32 shift = (current_effect->spectral_shift * height) >> 8;
/* begin CS */ /* begin CS */
g_return_if_fail(SDL_mutexP(pcm_data_mutex) >= 0); g_return_if_fail(SDL_mutexP(pcm_data_mutex) >= 0);
y1 = (gfloat)((((pcm_data[0][0] + pcm_data[1][0]) >> 9) * current_effect->spectral_amplitude * scr_par.height) >> 12); y1 = (gfloat)((((pcm_data[0][0] + pcm_data[1][0]) >> 9) * current_effect->spectral_amplitude * height) >> 12);
y2 = (gfloat)((((pcm_data[0][0] + pcm_data[1][0]) >> 9) * current_effect->spectral_amplitude * scr_par.height) >> 12); y2 = (gfloat)((((pcm_data[0][0] + pcm_data[1][0]) >> 9) * current_effect->spectral_amplitude * height) >> 12);
if (cosw.i != scr_par.width || sinw.i != scr_par.width) { if (cosw.i != width || sinw.i != width) {
g_free(cosw.f); g_free(cosw.f);
g_free(sinw.f); g_free(sinw.f);
sinw.f = cosw.f = NULL; sinw.f = cosw.f = NULL;
@ -315,21 +315,21 @@ void spectral(t_effect *current_effect)
} }
if (cosw.i == 0 || cosw.f == NULL) { if (cosw.i == 0 || cosw.f == NULL) {
gfloat halfPI = (gfloat)PI / 2; gfloat halfPI = (gfloat)PI / 2;
cosw.i = scr_par.width; cosw.i = width;
if (cosw.f != NULL) if (cosw.f != NULL)
g_free(cosw.f); g_free(cosw.f);
cosw.f = g_malloc(sizeof(gfloat) * scr_par.width); cosw.f = g_malloc(sizeof(gfloat) * width);
for (i = 0; i < scr_par.width; i += step) for (i = 0; i < width; i += step)
cosw.f[i] = cos((gfloat)i / scr_par.width * PI + halfPI); cosw.f[i] = cos((gfloat)i / width * PI + halfPI);
} }
if (sinw.i == 0 || sinw.f == NULL) { if (sinw.i == 0 || sinw.f == NULL) {
gfloat halfPI = (gfloat)PI / 2; gfloat halfPI = (gfloat)PI / 2;
sinw.i = scr_par.width; sinw.i = width;
if (sinw.f != NULL) if (sinw.f != NULL)
g_free(sinw.f); g_free(sinw.f);
sinw.f = g_malloc(sizeof(gfloat) * scr_par.width); sinw.f = g_malloc(sizeof(gfloat) * width);
for (i = 0; i < scr_par.width; i += step) for (i = 0; i < width; i += step)
sinw.f[i] = sin((gfloat)i / scr_par.width * PI + halfPI); sinw.f[i] = sin((gfloat)i / width * PI + halfPI);
} }
if (current_effect->mode_spectre == 3) { if (current_effect->mode_spectre == 3) {
if (y1 < 0.0) if (y1 < 0.0)
@ -337,15 +337,15 @@ void spectral(t_effect *current_effect)
if (y2 < 0.0) if (y2 < 0.0)
y2 = 0.0; y2 = 0.0;
} }
halfheight = scr_par.height >> 1; halfheight = height >> 1;
halfwidth = scr_par.width >> 1; halfwidth = width >> 1;
for (i = step; i < scr_par.width; i += step) { for (i = step; i < width; i += step) {
old_y1 = y1; old_y1 = y1;
old_y2 = y2; old_y2 = y2;
y1 = (gfloat)(((pcm_data[1][(i << 9) / scr_par.width / density_lines] >> 8) * y1 = (gfloat)(((pcm_data[1][(i << 9) / width / density_lines] >> 8) *
current_effect->spectral_amplitude * scr_par.height) >> 12); current_effect->spectral_amplitude * height) >> 12);
y2 = (gfloat)(((pcm_data[0][(i << 9) / scr_par.width / density_lines] >> 8) * y2 = (gfloat)(((pcm_data[0][(i << 9) / width / density_lines] >> 8) *
current_effect->spectral_amplitude * scr_par.height) >> 12); current_effect->spectral_amplitude * height) >> 12);
/* end CS */ /* end CS */
switch (current_effect->mode_spectre) { switch (current_effect->mode_spectre) {
case 0: case 0:
@ -396,10 +396,10 @@ void spectral(t_effect *current_effect)
} }
g_return_if_fail(SDL_mutexV(pcm_data_mutex) >= 0); g_return_if_fail(SDL_mutexV(pcm_data_mutex) >= 0);
if (current_effect->mode_spectre == 3 || current_effect->mode_spectre == 4) { if (current_effect->mode_spectre == 3 || current_effect->mode_spectre == 4) {
line(halfwidth + cosw.f[scr_par.width - step] * (shift + y1), line(halfwidth + cosw.f[width - step] * (shift + y1),
halfheight + sinw.f[scr_par.width - step] * (shift + y1), halfheight + sinw.f[width - step] * (shift + y1),
halfwidth - cosw.f[scr_par.width - step] * (shift + y2), halfwidth - cosw.f[width - step] * (shift + y2),
halfheight + sinw.f[scr_par.width - step] * (shift + y2), halfheight + sinw.f[width - step] * (shift + y2),
current_effect->spectral_color); current_effect->spectral_color);
} }
} }
@ -420,10 +420,10 @@ void curve(t_effect *current_effect)
vr = 0.001; vr = 0.001;
k = current_effect->x_curve; k = current_effect->x_curve;
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
x = cos((gfloat)(k) / (v + v * j * 1.34)) * scr_par.height * amplitude; x = cos((gfloat)(k) / (v + v * j * 1.34)) * height * amplitude;
y = sin((gfloat)(k) / (1.756 * (v + v * j * 0.93))) * scr_par.height * amplitude; y = sin((gfloat)(k) / (1.756 * (v + v * j * 0.93))) * height * amplitude;
plot2(x * cos((gfloat)k * vr) + y * sin((gfloat)k * vr) + scr_par.width / 2, plot2(x * cos((gfloat)k * vr) + y * sin((gfloat)k * vr) + width / 2,
x * sin((gfloat)k * vr) - y * cos((gfloat)k * vr) + scr_par.height / 2, x * sin((gfloat)k * vr) - y * cos((gfloat)k * vr) + height / 2,
(byte)current_effect->curve_color); (byte)current_effect->curve_color);
k++; k++;
} }

View File

@ -19,26 +19,19 @@
#include <glib.h> #include <glib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <libaudcore/drct.h>
#include <libaudcore/playlist.h>
#include <libaudcore/plugins.h>
#include <libaudcore/runtime.h>
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <SDL/SDL_thread.h> #include <SDL/SDL_thread.h>
/*#include <SDL/SDL_syswm.h>*/ /*#include <SDL/SDL_syswm.h>*/
extern "C" {
#include "config.h" #include "config.h"
#include "display.h" #include "display.h"
#include "effects.h" #include "effects.h"
#include "renderer.h" #include "infinity.h"
#include "types.h" #include "types.h"
#if MMX_DETECTION #if MMX_DETECTION
#include "cputest.h" #include "cputest.h"
#endif #endif
}
#define wrap(a) (a < 0 ? 0 : (a > 255 ? 255 : a)) #define wrap(a) (a < 0 ? 0 : (a > 255 ? 255 : a))
#define next_effect() (t_last_effect++) #define next_effect() (t_last_effect++)
@ -47,8 +40,10 @@ extern "C" {
typedef gint32 t_color; typedef gint32 t_color;
typedef gint32 t_num_effect; typedef gint32 t_num_effect;
static t_screen_parameters scr_par; static InfParameters * params;
static Player * player;
static gint32 width, height, scale;
static t_effect current_effect; static t_effect current_effect;
static t_color color, old_color, t_last_color; static t_color color, old_color, t_last_color;
static t_num_effect t_last_effect; static t_num_effect t_last_effect;
@ -72,7 +67,7 @@ static void check_events();
static int renderer(void *); static int renderer(void *);
static void set_title(void); static void set_title(void);
void renderer_init(void) void infinity_init(InfParameters * _params, Player * _player)
{ {
gint32 _try; gint32 _try;
@ -87,9 +82,11 @@ void renderer_init(void)
} }
} }
initializing = TRUE; initializing = TRUE;
scr_par.width = aud_get_int(CFGID, "width"); params = _params;
scr_par.height = aud_get_int(CFGID, "height"); player = _player;
scr_par.scale = aud_get_int(CFGID, "scale_factor"); width = params->get_width();
height = params->get_height();
scale = params->get_scale();
old_color = 0; old_color = 0;
color = 0; color = 0;
@ -103,7 +100,7 @@ void renderer_init(void)
quiting = FALSE; quiting = FALSE;
first_xevent = TRUE; first_xevent = TRUE;
display_init(scr_par.width, scr_par.height, scr_par.scale); display_init(width, height, scale);
current_title = g_strdup("Infinity"); current_title = g_strdup("Infinity");
set_title(); set_title();
title_timer = g_timer_new(); title_timer = g_timer_new();
@ -121,10 +118,9 @@ void renderer_init(void)
thread = SDL_CreateThread(renderer, NULL); thread = SDL_CreateThread(renderer, NULL);
} }
void renderer_finish(void) void infinity_finish(void)
{ {
gint32 _try; gint32 _try;
PluginHandle * plugin;
if (finished) if (finished)
return; return;
@ -142,7 +138,7 @@ void renderer_finish(void)
SDL_WaitThread(thread, NULL); SDL_WaitThread(thread, NULL);
SDL_DestroyMutex(resizing_mutex); SDL_DestroyMutex(resizing_mutex);
/* /*
* Take some time to let it know renderer_render_multi_pcm() * Take some time to let it know infinity_render_multi_pcm()
* that must not call display_set_pcm_data(). * that must not call display_set_pcm_data().
* If it do that while calling display_quit(), * If it do that while calling display_quit(),
* we could make Audacious crash, because display_quit * we could make Audacious crash, because display_quit
@ -155,13 +151,12 @@ void renderer_finish(void)
display_quit(); display_quit();
g_timer_destroy(title_timer); g_timer_destroy(title_timer);
plugin = aud_plugin_lookup_basename("libinfinite"); player->disable_plugin();
aud_plugin_enable(plugin, false);
g_message("Infinity: Closing..."); g_message("Infinity: Closing...");
} }
void renderer_render_multi_pcm(const float *data, int channels) void infinity_render_multi_pcm(const float *data, int channels)
{ {
if (!initializing && !quiting) if (!initializing && !quiting)
display_set_pcm_data(data, channels); display_set_pcm_data(data, channels);
@ -215,27 +210,25 @@ static gint32 event_filter(const SDL_Event *event)
static gint disable_func(gpointer data) static gint disable_func(gpointer data)
{ {
renderer_finish(); infinity_finish();
return FALSE; return FALSE;
} }
static void check_events() static void check_events()
{ {
SDL_Event event; SDL_Event event;
gint volume;
/*XEvent *xevent; /*XEvent *xevent;
* XWindowChanges changes; * XWindowChanges changes;
* XWindowAttributes attr; * XWindowAttributes attr;
* XSetWindowAttributes s_attr;*/ * XSetWindowAttributes s_attr;*/
if (aud_get_int(CFGID, "show_title")) { if (params->must_show_title()) {
if (g_timer_elapsed(title_timer, NULL) > 1.0) { if (g_timer_elapsed(title_timer, NULL) > 1.0) {
if (aud_drct_get_playing() && aud_drct_get_ready()) { if (player->is_playing()) {
if (current_title) if (current_title)
g_free(current_title); g_free(current_title);
String title = aud_playlist_get_title(aud_playlist_get_playing()); current_title = g_strdup(player->get_title());
current_title = g_strdup(title.to_raw());
} else { } else {
if (current_title) if (current_title)
g_free(current_title); g_free(current_title);
@ -283,49 +276,44 @@ static void check_events()
g_return_if_fail(SDL_LockMutex(resizing_mutex) >= 0); g_return_if_fail(SDL_LockMutex(resizing_mutex) >= 0);
resizing = TRUE; resizing = TRUE;
g_return_if_fail(SDL_UnlockMutex(resizing_mutex) >= 0); g_return_if_fail(SDL_UnlockMutex(resizing_mutex) >= 0);
scr_par.width = event.resize.w; width = event.resize.w;
scr_par.height = event.resize.h; height = event.resize.h;
g_message("Infinity: Screen resized to %dx%d pixels^2", g_message("Infinity: Screen resized to %dx%d pixels^2", width, height);
scr_par.width, scr_par.height);
must_resize = TRUE; must_resize = TRUE;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_RIGHT: case SDLK_RIGHT:
if (aud_drct_get_playing() && aud_drct_get_ready()) if (player->is_playing())
aud_drct_seek(aud_drct_get_time() + 5000); player->seek(5000);
break; break;
case SDLK_LEFT: case SDLK_LEFT:
if (aud_drct_get_playing() && aud_drct_get_ready()) if (player->is_playing())
aud_drct_seek(aud_drct_get_time() - 5000); player->seek(-5000);
break; break;
case SDLK_UP: case SDLK_UP:
volume = aud_drct_get_volume_main(); player->adjust_volume(5);
g_message("Increasing volume to %d", volume + 5);
aud_drct_set_volume_main(volume + 5);
break; break;
case SDLK_DOWN: case SDLK_DOWN:
volume = aud_drct_get_volume_main(); player->adjust_volume(-5);
g_message("Decreasing volume to %d", volume - 5);
aud_drct_set_volume_main(volume - 5);
break; break;
case SDLK_TAB: case SDLK_TAB:
display_toggle_fullscreen(); display_toggle_fullscreen();
break; break;
case SDLK_z: case SDLK_z:
aud_drct_pl_prev(); player->previous();
break; break;
case SDLK_x: case SDLK_x:
aud_drct_play(); player->play();
break; break;
case SDLK_c: case SDLK_c:
aud_drct_pause(); player->pause();
break; break;
case SDLK_v: case SDLK_v:
aud_drct_stop(); player->stop();
break; break;
case SDLK_b: case SDLK_b:
aud_drct_pl_next(); player->next();
break; break;
case SDLK_F11: case SDLK_F11:
display_save_screen(); display_save_screen();
@ -399,15 +387,16 @@ static gint64 calculate_frame_length_usecs(gint32 fps, int line) {
static int renderer(void *arg) static int renderer(void *arg)
{ {
gint64 now, render_time, t_begin;
gint32 frame_length; gint32 frame_length;
gint32 fps, new_fps; gint32 fps, new_fps;
gint32 t_between_effects, t_between_colors; gint32 t_between_effects, t_between_colors;
gint32 has_mmx = 0; gint32 has_mmx = 0;
fps = aud_get_int(CFGID, "max_fps"); fps = params->get_max_fps();
frame_length = calculate_frame_length_usecs(fps, __LINE__); frame_length = calculate_frame_length_usecs(fps, __LINE__);
t_between_effects = aud_get_int(CFGID, "effect_time"); t_between_effects = params->get_effect_interval();
t_between_colors = aud_get_int(CFGID, "palette_time"); t_between_colors = params->get_color_interval();
#if MMX_DETECTION #if MMX_DETECTION
has_mmx = mm_support_check_and_show(); has_mmx = mm_support_check_and_show();
#endif #endif
@ -424,19 +413,19 @@ static int renderer(void *arg)
if (finished) if (finished)
break; break;
if (must_resize) { if (must_resize) {
display_resize(scr_par.width, scr_par.height); display_resize(width, height);
aud_set_int(CFGID, "width", scr_par.width); params->set_width(width);
aud_set_int(CFGID, "heigth", scr_par.height); params->set_height(height);
must_resize = FALSE; must_resize = FALSE;
g_return_val_if_fail(SDL_LockMutex(resizing_mutex) >= 0, -1); g_return_val_if_fail(SDL_LockMutex(resizing_mutex) >= 0, -1);
resizing = FALSE; resizing = FALSE;
g_return_val_if_fail(SDL_UnlockMutex(resizing_mutex) >= 0, -1); g_return_val_if_fail(SDL_UnlockMutex(resizing_mutex) >= 0, -1);
} }
auto t_begin = g_get_monotonic_time(); t_begin = g_get_monotonic_time();
if (has_mmx) if (has_mmx)
display_blur_mmx(scr_par.width * scr_par.height * current_effect.num_effect); display_blur_mmx(width * height * current_effect.num_effect);
else else
display_blur(scr_par.width * scr_par.height * current_effect.num_effect); display_blur(width * height * current_effect.num_effect);
spectral(&current_effect); spectral(&current_effect);
curve(&current_effect); curve(&current_effect);
if (t_last_color <= 32) if (t_last_color <= 32)
@ -448,12 +437,12 @@ static int renderer(void *arg)
if (!mode_interactif) { if (!mode_interactif) {
display_load_random_effect(&current_effect); display_load_random_effect(&current_effect);
t_last_effect = 0; t_last_effect = 0;
t_between_effects = aud_get_int(CFGID, "effect_time"); t_between_effects = params->get_effect_interval();
} }
#else #else
display_load_random_effect(&current_effect); display_load_random_effect(&current_effect);
t_last_effect = 0; t_last_effect = 0;
t_between_effects = aud_get_int(CFGID, "effect_time"); t_between_effects = params->get_effect_interval();
#endif #endif
} }
if (t_last_color % t_between_colors == 0) { if (t_last_color % t_between_colors == 0) {
@ -462,24 +451,24 @@ static int renderer(void *arg)
old_color = color; old_color = color;
color = rand() % NB_PALETTES; color = rand() % NB_PALETTES;
t_last_color = 0; t_last_color = 0;
t_between_colors = aud_get_int(CFGID, "palette_time"); t_between_colors = params->get_color_interval();
} }
#else #else
old_color = color; old_color = color;
color = rand() % NB_PALETTES; color = rand() % NB_PALETTES;
t_last_color = 0; t_last_color = 0;
t_between_colors = aud_get_int(CFGID, "palette_time"); t_between_colors = params->get_color_interval();
#endif #endif
} }
new_fps = aud_get_int(CFGID, "max_fps"); new_fps = params->get_max_fps();
if (new_fps != fps) { if (new_fps != fps) {
fps = new_fps; fps = new_fps;
frame_length = calculate_frame_length_usecs(fps, __LINE__); frame_length = calculate_frame_length_usecs(fps, __LINE__);
} }
auto now = g_get_monotonic_time(); now = g_get_monotonic_time();
auto render_time = now - t_begin; render_time = now - t_begin;
if (render_time < frame_length) { if (render_time < frame_length) {
g_usleep(frame_length - render_time); g_usleep(frame_length - render_time);
} }

71
src/infinity.h Normal file
View File

@ -0,0 +1,71 @@
/*
* 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 Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __INFINITY_INFINITY__
#define __INFINITY_INFINITY__
#include <glib.h>
typedef struct _InfParameters {
gint32 (*get_x_origin) (void);
gint32 (*get_y_origin) (void);
gint32 (*get_width) (void);
void (*set_width) (gint32 width);
gint32 (*get_height) (void);
void (*set_height) (gint32 height);
gint32 (*get_scale) (void);
gint32 (*get_bpp) (void); /* bytes per pixels. */
gint32 (*get_effect_interval) (void);
gint32 (*get_color_interval) (void);
gint32 (*must_show_title) (void);
gint32 (*get_max_fps) (void);
} InfParameters;
typedef struct _Player {
gboolean (*is_playing) (void);
gchar* (*get_title) (void);
void (*play) (void);
void (*pause) (void);
void (*stop) (void);
void (*previous) (void);
void (*next) (void);
void (*seek) (gint32 usecs);
void (*adjust_volume) (gint delta);
void (*disable_plugin) (void); /* tell the player that this plugin has stopped */
} Player;
/*
* Initializes rendering process.
*
* Reads configuration parameters and launches a thread where most of the
* plugin job gets done.
*/
void infinity_init(InfParameters * params, Player * player);
/*
* Closes rendering process.
*/
void infinity_finish(void);
/*
* Expected to be called periodically by the player to provide actual PCM data.
*/
void infinity_render_multi_pcm(const float *data, int channels);
#endif /* __INFINITY_INFINITY__ */

View File

@ -1,41 +0,0 @@
/*
* 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 Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __INFINITY_RENDERER__
#define __INFINITY_RENDERER__
#include <glib.h>
/*
* Initializes rendering process.
*
* Reads configuration parameters and launchs a thread where most of the
* plugin job gets done.
*/
void renderer_init(void);
/*
* Closes rendering process.
*/
void renderer_finish(void);
/*
* Copies PCM data from Audacity.
*
* Called periodically by Audacity with actual PCM data.
*/
void renderer_render_multi_pcm(const float *data, int channels);
#endif /* __INFINITY_RENDERER__ */

View File

@ -18,17 +18,6 @@
#include <SDL/SDL.h> #include <SDL/SDL.h>
#define CFGID "infinity"
// existence of this header smells as bad design...
typedef struct _t_screen_parameters {
gint32 x, y;
gint32 width;
gint32 height;
gint32 scale;
gint32 bpp; /* bytes per pixels. */
} t_screen_parameters;
typedef Uint8 byte; typedef Uint8 byte;
#endif /* __INFINITY_TYPES__ */ #endif /* __INFINITY_TYPES__ */