Bring synaesthesia to next century.

Do proper size negotiation. Change engine API to allow resizes. Small cleanups elsewhere.
This commit is contained in:
Stefan Kost 2009-01-24 23:27:08 +02:00
parent d798fa10c9
commit 8ebd13a681
4 changed files with 131 additions and 105 deletions

View file

@ -38,7 +38,6 @@
#include "gstsynaesthesia.h" #include "gstsynaesthesia.h"
/* elementfactory information */ /* elementfactory information */
static const GstElementDetails gst_synaesthesia_details = static const GstElementDetails gst_synaesthesia_details =
GST_ELEMENT_DETAILS ("Synaesthesia", GST_ELEMENT_DETAILS ("Synaesthesia",
@ -79,7 +78,7 @@ static GstFlowReturn gst_synaesthesia_chain (GstPad * pad, GstBuffer * buffer);
static GstStateChangeReturn static GstStateChangeReturn
gst_synaesthesia_change_state (GstElement * element, GstStateChange transition); gst_synaesthesia_change_state (GstElement * element, GstStateChange transition);
static GstCaps *gst_synaesthesia_src_getcaps (GstPad * pad); static gboolean gst_synaesthesia_src_negotiate (GstSynaesthesia * synaesthesia);
static gboolean gst_synaesthesia_src_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_synaesthesia_src_setcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_synaesthesia_sink_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_synaesthesia_sink_setcaps (GstPad * pad, GstCaps * caps);
@ -157,8 +156,6 @@ gst_synaesthesia_init (GstSynaesthesia * synaesthesia)
synaesthesia->srcpad = synaesthesia->srcpad =
gst_pad_new_from_static_template (&gst_synaesthesia_src_template, "src"); gst_pad_new_from_static_template (&gst_synaesthesia_src_template, "src");
gst_pad_set_getcaps_function (synaesthesia->srcpad,
GST_DEBUG_FUNCPTR (gst_synaesthesia_src_getcaps));
gst_pad_set_setcaps_function (synaesthesia->srcpad, gst_pad_set_setcaps_function (synaesthesia->srcpad,
GST_DEBUG_FUNCPTR (gst_synaesthesia_src_setcaps)); GST_DEBUG_FUNCPTR (gst_synaesthesia_src_setcaps));
gst_element_add_pad (GST_ELEMENT (synaesthesia), synaesthesia->srcpad); gst_element_add_pad (GST_ELEMENT (synaesthesia), synaesthesia->srcpad);
@ -166,8 +163,8 @@ gst_synaesthesia_init (GstSynaesthesia * synaesthesia)
synaesthesia->adapter = gst_adapter_new (); synaesthesia->adapter = gst_adapter_new ();
/* reset the initial video state */ /* reset the initial video state */
synaesthesia->width = SYNAES_WIDTH; synaesthesia->width = 320;
synaesthesia->height = SYNAES_HEIGHT; synaesthesia->height = 200;
synaesthesia->fps_n = 25; /* desired frame rate */ synaesthesia->fps_n = 25; /* desired frame rate */
synaesthesia->fps_d = 1; synaesthesia->fps_d = 1;
synaesthesia->frame_duration = -1; synaesthesia->frame_duration = -1;
@ -178,10 +175,6 @@ gst_synaesthesia_init (GstSynaesthesia * synaesthesia)
synaesthesia->next_ts = GST_CLOCK_TIME_NONE; synaesthesia->next_ts = GST_CLOCK_TIME_NONE;
/* FIXME: the size is currently ignored by the engine. It should
* not be, and also there should be a way to change the size later.
* We also need API to negotiate the spf (samples_per_frame)
* we can supply. */
synaesthesia->si = synaesthesia->si =
synaesthesia_new (synaesthesia->width, synaesthesia->height); synaesthesia_new (synaesthesia->width, synaesthesia->height);
} }
@ -265,33 +258,52 @@ wrong_rate:
} }
} }
static GstCaps * static gboolean
gst_synaesthesia_src_getcaps (GstPad * pad) gst_synaesthesia_src_negotiate (GstSynaesthesia * synaesthesia)
{ {
GstSynaesthesia *synaesthesia; GstCaps *othercaps, *target, *intersect;
GstCaps *caps; GstStructure *structure;
const GstCaps *templcaps; const GstCaps *templ;
gint i;
synaesthesia = GST_SYNAESTHESIA (gst_pad_get_parent (pad)); templ = gst_pad_get_pad_template_caps (synaesthesia->srcpad);
templcaps = gst_pad_get_pad_template_caps (pad);
caps = gst_caps_copy (templcaps);
for (i = 0; i < gst_caps_get_size (caps); i++) { GST_DEBUG_OBJECT (synaesthesia, "performing negotiation");
GstStructure *structure = gst_caps_get_structure (caps, i);
gst_structure_set (structure, /* see what the peer can do */
"width", G_TYPE_INT, synaesthesia->width, othercaps = gst_pad_peer_get_caps (synaesthesia->srcpad);
"height", G_TYPE_INT, synaesthesia->height, if (othercaps) {
"framerate", GST_TYPE_FRACTION, synaesthesia->fps_n, intersect = gst_caps_intersect (othercaps, templ);
synaesthesia->fps_d, NULL); gst_caps_unref (othercaps);
if (gst_caps_is_empty (intersect))
goto no_format;
target = gst_caps_copy_nth (intersect, 0);
gst_caps_unref (intersect);
} else {
target = gst_caps_ref ((GstCaps *) templ);
} }
gst_object_unref (synaesthesia); structure = gst_caps_get_structure (target, 0);
gst_structure_fixate_field_nearest_int (structure, "width",
synaesthesia->width);
gst_structure_fixate_field_nearest_int (structure, "height",
synaesthesia->height);
gst_structure_fixate_field_nearest_fraction (structure, "framerate",
synaesthesia->fps_n, synaesthesia->fps_d);
GST_DEBUG ("final caps are %" GST_PTR_FORMAT, caps); GST_DEBUG ("final caps are %" GST_PTR_FORMAT, target);
return caps; gst_pad_set_caps (synaesthesia->srcpad, target);
gst_caps_unref (target);
return TRUE;
no_format:
{
gst_caps_unref (intersect);
return FALSE;
}
} }
static gboolean static gboolean
@ -312,23 +324,22 @@ gst_synaesthesia_src_setcaps (GstPad * pad, GstCaps * caps)
goto missing_caps_details; goto missing_caps_details;
} }
if ((w != SYNAES_WIDTH) || (h != SYNAES_HEIGHT))
goto wrong_resolution;
synaesthesia->width = w; synaesthesia->width = w;
synaesthesia->height = h; synaesthesia->height = h;
synaesthesia->fps_n = num; synaesthesia->fps_n = num;
synaesthesia->fps_d = denom; synaesthesia->fps_d = denom;
synaesthesia_resize (synaesthesia->si, synaesthesia->width,
synaesthesia->height);
synaesthesia->frame_duration = gst_util_uint64_scale_int (GST_SECOND, synaesthesia->frame_duration = gst_util_uint64_scale_int (GST_SECOND,
synaesthesia->fps_d, synaesthesia->fps_n); synaesthesia->fps_d, synaesthesia->fps_n);
synaesthesia->spf = gst_util_uint64_scale_int (synaesthesia->rate, synaesthesia->spf = gst_util_uint64_scale_int (synaesthesia->rate,
synaesthesia->fps_d, synaesthesia->fps_n); synaesthesia->fps_d, synaesthesia->fps_n);
/* FIXME: the size is currently ignored by the engine. see comment above */ GST_DEBUG_OBJECT (synaesthesia, "dimension %dx%d, framerate %d/%d, spf %d",
synaesthesia_close (synaesthesia->si); synaesthesia->width, synaesthesia->height,
synaesthesia->si = synaesthesia->fps_n, synaesthesia->fps_d, synaesthesia->spf);
synaesthesia_new (synaesthesia->width, synaesthesia->height);
done: done:
gst_object_unref (synaesthesia); gst_object_unref (synaesthesia);
@ -341,14 +352,6 @@ missing_caps_details:
res = FALSE; res = FALSE;
goto done; goto done;
} }
wrong_resolution:
{
GST_WARNING_OBJECT (synaesthesia,
"unsupported resolution: %d x %d (wanted %d x %d)", w, h, SYNAES_WIDTH,
SYNAES_HEIGHT);
res = FALSE;
goto done;
}
} }
static GstFlowReturn static GstFlowReturn
@ -360,7 +363,7 @@ gst_synaesthesia_chain (GstPad * pad, GstBuffer * buffer)
synaesthesia = GST_SYNAESTHESIA (gst_pad_get_parent (pad)); synaesthesia = GST_SYNAESTHESIA (gst_pad_get_parent (pad));
GST_DEBUG ("chainfunc called"); GST_LOG ("chainfunc called");
/* resync on DISCONT */ /* resync on DISCONT */
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
@ -369,16 +372,8 @@ gst_synaesthesia_chain (GstPad * pad, GstBuffer * buffer)
} }
if (GST_PAD_CAPS (synaesthesia->srcpad) == NULL) { if (GST_PAD_CAPS (synaesthesia->srcpad) == NULL) {
GstCaps *target; if (!gst_synaesthesia_src_negotiate (synaesthesia))
GST_DEBUG ("fixating");
if ((target = gst_synaesthesia_src_getcaps (synaesthesia->srcpad))) {
gst_pad_set_caps (synaesthesia->srcpad, target);
gst_caps_unref (target);
} else {
GST_DEBUG ("no caps on srcpad");
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
}
} }
/* Match timestamps from the incoming audio */ /* Match timestamps from the incoming audio */
@ -388,15 +383,11 @@ gst_synaesthesia_chain (GstPad * pad, GstBuffer * buffer)
gst_adapter_push (synaesthesia->adapter, buffer); gst_adapter_push (synaesthesia->adapter, buffer);
/* this is what we want */ /* this is what we want */
bytesperread = SYNAES_SAMPLES * synaesthesia->channels * sizeof (gint16); bytesperread = MAX (FFT_BUFFER_SIZE, synaesthesia->spf) * synaesthesia->channels * sizeof (gint16);
/* FIXME: what about:
bytesperread = MAX (SYNAES_SAMPLES, synaesthesia->spf) * synaesthesia->channels * sizeof (gint16);
*/
/* this is what we have */ /* this is what we have */
avail = gst_adapter_available (synaesthesia->adapter); avail = gst_adapter_available (synaesthesia->adapter);
while (avail > while (avail > bytesperread) {
MAX (bytesperread,
synaesthesia->spf * synaesthesia->channels * sizeof (gint16))) {
const guint16 *data = const guint16 *data =
(const guint16 *) gst_adapter_peek (synaesthesia->adapter, (const guint16 *) gst_adapter_peek (synaesthesia->adapter,
bytesperread); bytesperread);
@ -405,7 +396,7 @@ gst_synaesthesia_chain (GstPad * pad, GstBuffer * buffer)
guint i; guint i;
/* deinterleave */ /* deinterleave */
for (i = 0; i < SYNAES_SAMPLES; i++) { for (i = 0; i < FFT_BUFFER_SIZE; i++) {
synaesthesia->datain[0][i] = *data++; synaesthesia->datain[0][i] = *data++;
synaesthesia->datain[1][i] = *data++; synaesthesia->datain[1][i] = *data++;
} }

View file

@ -29,17 +29,11 @@
#include "synaescope.h" #include "synaescope.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define SYNAES_SAMPLES 512
#define SYNAES_WIDTH 320
#define SYNAES_HEIGHT 200
#define GST_TYPE_SYNAESTHESIA (gst_synaesthesia_get_type()) #define GST_TYPE_SYNAESTHESIA (gst_synaesthesia_get_type())
#define GST_SYNAESTHESIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SYNAESTHESIA,GstSynaesthesia)) #define GST_SYNAESTHESIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SYNAESTHESIA,GstSynaesthesia))
#define GST_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SYNAESTHESIA,GstSynaesthesiaClass)) #define GST_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SYNAESTHESIA,GstSynaesthesiaClass))
#define GST_IS_SYNAESTHESIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SYNAESTHESIA)) #define GST_IS_SYNAESTHESIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SYNAESTHESIA))
#define GST_IS_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SYNAESTHESIA)) #define GST_IS_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SYNAESTHESIA))
typedef struct _GstSynaesthesia GstSynaesthesia; typedef struct _GstSynaesthesia GstSynaesthesia;
typedef struct _GstSynaesthesiaClass GstSynaesthesiaClass; typedef struct _GstSynaesthesiaClass GstSynaesthesiaClass;
@ -59,7 +53,7 @@ struct _GstSynaesthesia
guint bps; /* bytes per sample */ guint bps; /* bytes per sample */
guint spf; /* samples per video frame */ guint spf; /* samples per video frame */
gint16 datain[2][SYNAES_SAMPLES]; gint16 datain[2][FFT_BUFFER_SIZE];
/* video state */ /* video state */
gint fps_n, fps_d; gint fps_n, fps_d;
@ -83,5 +77,4 @@ struct _GstSynaesthesiaClass
GType gst_synaesthesia_get_type (void); GType gst_synaesthesia_get_type (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_SYNAESTHESIA_H__ */ #endif /* __GST_SYNAESTHESIA_H__ */

View file

@ -47,11 +47,6 @@
#define SCOPE_BG_GREEN 0 #define SCOPE_BG_GREEN 0
#define SCOPE_BG_BLUE 0 #define SCOPE_BG_BLUE 0
#define FFT_BUFFER_SIZE_LOG 9
#define FFT_BUFFER_SIZE (1 << FFT_BUFFER_SIZE_LOG)
#define syn_width 320
#define syn_height 200
#define brightMin 200 #define brightMin 200
#define brightMax 2000 #define brightMax 2000
#define brightDec 10 #define brightDec 10
@ -65,10 +60,14 @@
/* Instance data */ /* Instance data */
struct syn_instance struct syn_instance
{ {
/* options */
unsigned int resx, resy;
int autobrightness; /* Whether to use automatic brightness adjust */ int autobrightness; /* Whether to use automatic brightness adjust */
unsigned int brightFactor; unsigned int brightFactor;
unsigned char output[syn_width * syn_height * 2];
guint32 display[syn_width * syn_height]; /* data */
unsigned char *output;
guint32 *display;
gint16 pcmt_l[FFT_BUFFER_SIZE]; gint16 pcmt_l[FFT_BUFFER_SIZE];
gint16 pcmt_r[FFT_BUFFER_SIZE]; gint16 pcmt_r[FFT_BUFFER_SIZE];
gint16 pcm_l[FFT_BUFFER_SIZE]; gint16 pcm_l[FFT_BUFFER_SIZE];
@ -92,14 +91,14 @@ static void synaes_fft (double *x, double *y);
static void synaescope_coreGo (syn_instance * si); static void synaescope_coreGo (syn_instance * si);
static inline void static inline void
addPixel (unsigned char *output, int x, int y, int br1, int br2) addPixel (syn_instance * si, int x, int y, int br1, int br2)
{ {
unsigned char *p; unsigned char *p;
if (x < 0 || x >= syn_width || y < 0 || y >= syn_height) if (G_UNLIKELY (x < 0 || x >= si->resx || y < 0 || y >= si->resy))
return; return;
p = output + x * 2 + y * syn_width * 2; p = si->output + x * 2 + y * si->resx * 2;
if (p[0] < 255 - br1) if (p[0] < 255 - br1)
p[0] += br1; p[0] += br1;
else else
@ -161,7 +160,7 @@ synaescope_coreGo (syn_instance * si)
/* Asger Alstrupt's optimized 32 bit fade */ /* Asger Alstrupt's optimized 32 bit fade */
/* (alstrup@diku.dk) */ /* (alstrup@diku.dk) */
ptr = (guint32 *) si->output; ptr = (guint32 *) si->output;
end = (guint32 *) (si->output + syn_width * syn_height * 2); end = (guint32 *) (si->output + si->resx * si->resy * 2);
do { do {
/*Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4; */ /*Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4; */
if (*ptr) { if (*ptr) {
@ -181,22 +180,22 @@ synaescope_coreGo (syn_instance * si)
ptr++; ptr++;
} while (ptr < end); } while (ptr < end);
heightFactor = FFT_BUFFER_SIZE / 2 / syn_height + 1; heightFactor = FFT_BUFFER_SIZE / 2 / si->resy + 1;
actualHeight = FFT_BUFFER_SIZE / 2 / heightFactor; actualHeight = FFT_BUFFER_SIZE / 2 / heightFactor;
heightAdd = (syn_height + actualHeight) >> 1; heightAdd = (si->resy + actualHeight) >> 1;
/* Correct for window size */ /* Correct for window size */
brightFactor2 = (si->brightFactor / 65536.0 / FFT_BUFFER_SIZE) * brightFactor2 = (si->brightFactor / 65536.0 / FFT_BUFFER_SIZE) *
sqrt (actualHeight * syn_width / (320.0 * 200.0)); sqrt (actualHeight * si->resx / (320.0 * 200.0));
brtot = 0; brtot = 0;
for (i = 1; i < FFT_BUFFER_SIZE / 2; i++) { for (i = 1; i < FFT_BUFFER_SIZE / 2; i++) {
/*int h = (int)( corr_r[i]*280 / (corr_l[i]+corr_r[i]+0.0001)+20 ); */ /*int h = (int)( corr_r[i]*280 / (corr_l[i]+corr_r[i]+0.0001)+20 ); */
if (si->corr_l[i] > 0 || si->corr_r[i] > 0) { if (si->corr_l[i] > 0 || si->corr_r[i] > 0) {
int h = int h =
(int) (si->corr_r[i] * syn_width / (si->corr_l[i] + si->corr_r[i])); (int) (si->corr_r[i] * si->resx / (si->corr_l[i] + si->corr_r[i]));
/* int h = (int)( syn_width - 1 ); */ /* int h = (int)( si->resx - 1 ); */
int br1, br2, br = int br1, br2, br =
(int) ((si->corr_l[i] + si->corr_r[i]) * i * brightFactor2); (int) ((si->corr_l[i] + si->corr_r[i]) * i * brightFactor2);
int px = h, py = heightAdd - i / heightFactor; int px = h, py = heightAdd - i / heightFactor;
@ -212,19 +211,19 @@ synaescope_coreGo (syn_instance * si)
br2 = 0; br2 = 0;
else if (br2 > 255) else if (br2 > 255)
br2 = 255; br2 = 255;
/*unsigned char *p = output+ h*2+(164-((i<<8)>>FFT_BUFFER_SIZE_LOG))*(syn_width*2); */ /*unsigned char *p = output+ h*2+(164-((i<<8)>>FFT_BUFFER_SIZE_LOG))*(si->resx*2); */
if (px < 30 || py < 30 || px > syn_width - 30 || py > syn_height - 30) { if (px < 30 || py < 30 || px > si->resx - 30 || py > si->resy - 30) {
addPixel (si->output, px, py, br1, br2); addPixel (si, px, py, br1, br2);
for (j = 1; br1 > 0 || br2 > 0; for (j = 1; br1 > 0 || br2 > 0;
j++, br1 = scaleDown[br1], br2 = scaleDown[br2]) { j++, br1 = scaleDown[br1], br2 = scaleDown[br2]) {
addPixel (si->output, px + j, py, br1, br2); addPixel (si, px + j, py, br1, br2);
addPixel (si->output, px, py + j, br1, br2); addPixel (si, px, py + j, br1, br2);
addPixel (si->output, px - j, py, br1, br2); addPixel (si, px - j, py, br1, br2);
addPixel (si->output, px, py - j, br1, br2); addPixel (si, px, py - j, br1, br2);
} }
} else { } else {
unsigned char *p = si->output + px * 2 + py * syn_width * 2, *p1 = unsigned char *p = si->output + px * 2 + py * si->resx * 2, *p1 =
p, *p2 = p, *p3 = p, *p4 = p; p, *p2 = p, *p3 = p, *p4 = p;
addPixelFast (p, br1, br2); addPixelFast (p, br1, br2);
for (; br1 > 0 || br2 > 0; br1 = scaleDown[br1], br2 = scaleDown[br2]) { for (; br1 > 0 || br2 > 0; br1 = scaleDown[br1], br2 = scaleDown[br2]) {
@ -232,9 +231,9 @@ synaescope_coreGo (syn_instance * si)
addPixelFast (p1, br1, br2); addPixelFast (p1, br1, br2);
p2 -= 2; p2 -= 2;
addPixelFast (p2, br1, br2); addPixelFast (p2, br1, br2);
p3 += syn_width * 2; p3 += si->resx * 2;
addPixelFast (p3, br1, br2); addPixelFast (p3, br1, br2);
p4 -= syn_width * 2; p4 -= si->resx * 2;
addPixelFast (p4, br1, br2); addPixelFast (p4, br1, br2);
} }
} }
@ -274,7 +273,7 @@ synaescope32 (syn_instance * si)
synaescope_coreGo (si); synaescope_coreGo (si);
outptr = si->output; outptr = si->output;
for (i = 0; i < syn_width * syn_height; i++) { for (i = 0; i < si->resx * si->resy; i++) {
si->display[i] = colEq[(outptr[0] >> 4) + (outptr[1] & 0xf0)]; si->display[i] = colEq[(outptr[0] >> 4) + (outptr[1] & 0xf0)];
outptr += 2; outptr += 2;
} }
@ -326,7 +325,7 @@ synaes_fft (double *x, double *y)
} }
static void static void
synaescope_set_data (syn_instance * si, gint16 data[2][512]) synaescope_set_data (syn_instance * si, gint16 data[2][FFT_BUFFER_SIZE])
{ {
int i; int i;
gint16 *newset_l = si->pcmt_l; gint16 *newset_l = si->pcmt_l;
@ -340,7 +339,7 @@ synaescope_set_data (syn_instance * si, gint16 data[2][512])
guint32 * guint32 *
synaesthesia_update (syn_instance * si, gint16 data[2][512]) synaesthesia_update (syn_instance * si, gint16 data[2][FFT_BUFFER_SIZE])
{ {
synaescope_set_data (si, data); synaescope_set_data (si, data);
synaescope32 (si); synaescope32 (si);
@ -390,8 +389,38 @@ synaesthesia_init ()
inited = 1; inited = 1;
} }
gboolean
synaesthesia_resize (syn_instance * si, guint resx, guint resy)
{
unsigned char *output = NULL;
guint32 *display = NULL;
/* FIXME: FFT_BUFFER_SIZE is reated to resy, right now we get black borders on
* top and below
*/
output = g_try_new (unsigned char, 2 * resx * resy);
display = g_try_new (guint32, resx * resy);
if (!output || !display)
goto Error;
g_free (si->output);
g_free (si->display);
si->resx = resx;
si->resy = resy;
si->output = output;
si->display = display;
return TRUE;
Error:
g_free (output);
g_free (display);
return FALSE;
}
syn_instance * syn_instance *
synaesthesia_new (guint32 resx, guint32 resy) synaesthesia_new (guint resx, guint resy)
{ {
syn_instance *si; syn_instance *si;
@ -399,11 +428,14 @@ synaesthesia_new (guint32 resx, guint32 resy)
if (si == NULL) if (si == NULL)
return NULL; return NULL;
if (!synaesthesia_resize (si, resx, resy)) {
g_free (si);
return NULL;
}
si->autobrightness = 1; /* Whether to use automatic brightness adjust */ si->autobrightness = 1; /* Whether to use automatic brightness adjust */
si->brightFactor = 400; si->brightFactor = 400;
/* FIXME: Make the width and height configurable? */
return si; return si;
} }
@ -412,5 +444,8 @@ synaesthesia_close (syn_instance * si)
{ {
g_return_if_fail (si != NULL); g_return_if_fail (si != NULL);
g_free (si->output);
g_free (si->display);
g_free (si); g_free (si);
} }

View file

@ -23,11 +23,18 @@
#include <glib.h> #include <glib.h>
/* FIXME: we should set this automatically based on height */
#define FFT_BUFFER_SIZE_LOG 10
#define FFT_BUFFER_SIZE (1 << FFT_BUFFER_SIZE_LOG)
typedef struct syn_instance syn_instance; typedef struct syn_instance syn_instance;
void synaesthesia_init (); void synaesthesia_init ();
syn_instance *synaesthesia_new (guint32 resx, guint32 resy); syn_instance *synaesthesia_new (guint resx, guint resy);
void synaesthesia_close (syn_instance *si); void synaesthesia_close (syn_instance * si);
guint32 * synaesthesia_update (syn_instance *si, gint16 data [2][512]);
gboolean synaesthesia_resize (syn_instance * si, guint resx, guint resy);
guint32 *synaesthesia_update (syn_instance * si,
gint16 data[2][FFT_BUFFER_SIZE]);
#endif #endif