mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
Bring synaesthesia to next century.
Do proper size negotiation. Change engine API to allow resizes. Small cleanups elsewhere.
This commit is contained in:
parent
d798fa10c9
commit
8ebd13a681
4 changed files with 131 additions and 105 deletions
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue