summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2016-01-28 09:43:12 +0100
committerStefan Sauer <ensonic@users.sf.net>2016-02-12 21:01:03 +0100
commit8d17911b33a0d8cfd0dedd09bfd99cf5eab777f7 (patch)
treee92f63e1215c9cc4b0f383f7ba2645e842f3d3c7
parent3d23ceebae48b9994e76581e8c97cbefc8c5bc55 (diff)
downloadgstreamer-plugins-good-8d17911b33a0d8cfd0dedd09bfd99cf5eab777f7.tar.gz
monoscpe: make the convolver use dynamic memory
Replace all #defines with members and initialize the convolver with a parameter.
-rw-r--r--gst/monoscope/convolve.c70
-rw-r--r--gst/monoscope/convolve.h10
-rw-r--r--gst/monoscope/monoscope.c19
-rw-r--r--gst/monoscope/monoscope.h17
4 files changed, 63 insertions, 53 deletions
diff --git a/gst/monoscope/convolve.c b/gst/monoscope/convolve.c
index 913773431..35f18ece5 100644
--- a/gst/monoscope/convolve.c
+++ b/gst/monoscope/convolve.c
@@ -83,14 +83,13 @@ typedef union stack_entry_s
}
stack_entry;
-#define STACK_SIZE (CONVOLVE_DEPTH * 3)
-
struct _struct_convolve_state
{
- double left[CONVOLVE_BIG];
- double right[CONVOLVE_SMALL * 3];
- double scratch[CONVOLVE_SMALL * 3];
- stack_entry stack[STACK_SIZE + 1];
+ int depth, small, big, stack_size;
+ double *left;
+ double *right;
+ double *scratch;
+ stack_entry *stack;
};
/*
@@ -100,9 +99,20 @@ struct _struct_convolve_state
* The pointer should be freed when it is finished with, by convolve_close().
*/
convolve_state *
-convolve_init (void)
+convolve_init (int depth)
{
- return (convolve_state *) calloc (1, sizeof (convolve_state));
+ convolve_state *state;
+
+ state = malloc (sizeof (convolve_state));
+ state->depth = depth;
+ state->small = (1 << depth);
+ state->big = (2 << depth);
+ state->stack_size = depth * 3;
+ state->left = calloc (state->big, sizeof (double));
+ state->right = calloc (state->small * 3, sizeof (double));
+ state->scratch = calloc (state->small * 3, sizeof (double));
+ state->stack = calloc (state->stack_size + 1, sizeof (stack_entry));
+ return state;
}
/*
@@ -111,6 +121,10 @@ convolve_init (void)
void
convolve_close (convolve_state * state)
{
+ free (state->left);
+ free (state->right);
+ free (state->scratch);
+ free (state->stack);
free (state);
}
@@ -273,13 +287,13 @@ convolve_match (const int *lastchoice, const short *input,
double *left = state->left;
double *right = state->right;
double *scratch = state->scratch;
- stack_entry *top = state->stack + (STACK_SIZE - 1);
+ stack_entry *top = state->stack + (state->stack_size - 1);
- for (i = 0; i < CONVOLVE_BIG; i++)
+ for (i = 0; i < state->big; i++)
left[i] = input[i];
- for (i = 0; i < CONVOLVE_SMALL; i++) {
- double a = lastchoice[(CONVOLVE_SMALL - 1) - i];
+ for (i = 0; i < state->small; i++) {
+ double a = lastchoice[(state->small - 1) - i];
right[i] = a;
avg += a;
@@ -288,32 +302,32 @@ convolve_match (const int *lastchoice, const short *input,
/* We adjust the smaller of the two input arrays to have average
* value 0. This makes the eventual result insensitive to both
* constant offsets and positive multipliers of the inputs. */
- avg /= CONVOLVE_SMALL;
- for (i = 0; i < CONVOLVE_SMALL; i++)
+ avg /= state->small;
+ for (i = 0; i < state->small; i++)
right[i] -= avg;
/* End-of-stack marker. */
top[1].b.null = scratch;
top[1].b.main = NULL;
- /* The low SMALLxSMALL, of which we want the high outputs. */
+ /* The low (small x small) part, of which we want the high outputs. */
top->v.left = left;
top->v.right = right;
- top->v.out = right + CONVOLVE_SMALL;
- convolve_run (top, CONVOLVE_SMALL, scratch);
+ top->v.out = right + state->small;
+ convolve_run (top, state->small, scratch);
- /* The high SMALLxSMALL, of which we want the low outputs. */
- top->v.left = left + CONVOLVE_SMALL;
+ /* The high (small x small) part, of which we want the low outputs. */
+ top->v.left = left + state->small;
top->v.right = right;
top->v.out = right;
- convolve_run (top, CONVOLVE_SMALL, scratch);
+ convolve_run (top, state->small, scratch);
/* Now find the best position amoungs this. Apart from the first
* and last, the required convolution outputs are formed by adding
* outputs from the two convolutions above. */
- best = right[CONVOLVE_BIG - 1];
- right[CONVOLVE_BIG + CONVOLVE_SMALL + 1] = 0;
+ best = right[state->big - 1];
+ right[state->big + state->small - 1] = 0;
p = -1;
- for (i = 0; i < CONVOLVE_SMALL; i++) {
- double a = right[i] + right[i + CONVOLVE_BIG];
+ for (i = 0; i < state->small; i++) {
+ double a = right[i] + right[i + state->big];
if (a > best) {
best = a;
@@ -326,18 +340,18 @@ convolve_match (const int *lastchoice, const short *input,
{
/* This is some debugging code... */
best = 0;
- for (i = 0; i < CONVOLVE_SMALL; i++)
+ for (i = 0; i < state->small; i++)
best += ((double) input[i + p]) * ((double) lastchoice[i] - avg);
- for (i = 0; i <= CONVOLVE_SMALL; i++) {
+ for (i = 0; i <= state->small; i++) {
double tot = 0;
unsigned int j;
- for (j = 0; j < CONVOLVE_SMALL; j++)
+ for (j = 0; j < state->small; j++)
tot += ((double) input[i + j]) * ((double) lastchoice[j] - avg);
if (tot > best)
printf ("(%i)", i);
- if (tot != left[i + (CONVOLVE_SMALL - 1)])
+ if (tot != left[i + (state->small - 1)])
printf ("!");
}
diff --git a/gst/monoscope/convolve.h b/gst/monoscope/convolve.h
index 64da74445..d6a7f05cc 100644
--- a/gst/monoscope/convolve.h
+++ b/gst/monoscope/convolve.h
@@ -31,16 +31,10 @@
extern "C" {
#endif
-/* convolve_match takes two blocks, one twice the size of the other. The
- * sizes of these are CONVOLVE_BIG and CONVOLVE_SMALL respectively. */
-#define CONVOLVE_DEPTH 8
-#define CONVOLVE_SMALL (1 << CONVOLVE_DEPTH)
-#define CONVOLVE_BIG (CONVOLVE_SMALL * 2)
-
-/* Convolution stuff */
+/* Convolution state */
typedef struct _struct_convolve_state convolve_state;
-convolve_state *convolve_init (void);
+convolve_state *convolve_init (int depth);
void convolve_close (convolve_state * state);
int convolve_match (const int * lastchoice,
diff --git a/gst/monoscope/monoscope.c b/gst/monoscope/monoscope.c
index e0c765165..9606a34b0 100644
--- a/gst/monoscope/monoscope.c
+++ b/gst/monoscope/monoscope.c
@@ -63,12 +63,12 @@ monoscope_init (guint32 resx, guint32 resy)
struct monoscope_state *stateptr;
/* I didn't program monoscope to only do 256*128, but it works that way */
- g_return_val_if_fail (resx == 256, 0);
- g_return_val_if_fail (resy == 128, 0);
+ g_return_val_if_fail (resx == scope_width, 0);
+ g_return_val_if_fail (resy == scope_height, 0);
stateptr = calloc (1, sizeof (struct monoscope_state));
if (stateptr == 0)
return 0;
- stateptr->cstate = convolve_init ();
+ stateptr->cstate = convolve_init (convolver_depth);
colors_init (stateptr->colors);
return stateptr;
}
@@ -81,9 +81,8 @@ monoscope_close (struct monoscope_state *stateptr)
}
guint32 *
-monoscope_update (struct monoscope_state *stateptr, gint16 data[512])
+monoscope_update (struct monoscope_state *stateptr, gint16 data[convolver_big])
{
- /* Note that CONVOLVE_BIG must == data size here, ie 512. */
/* Really, we want samples evenly spread over the available data.
* Just taking a continuous chunk will do for now, though. */
int i;
@@ -95,14 +94,14 @@ monoscope_update (struct monoscope_state *stateptr, gint16 data[512])
int factor;
int val;
int max = 1;
- short *thisEq = stateptr->copyEq;
+ gint16 *thisEq = stateptr->copyEq;
- memcpy (thisEq, data, sizeof (short) * CONVOLVE_BIG);
- val = convolve_match (stateptr->avgEq, stateptr->copyEq, stateptr->cstate);
+ memcpy (thisEq, data, sizeof (short) * convolver_big);
+ val = convolve_match (stateptr->avgEq, thisEq, stateptr->cstate);
thisEq += val;
- memset (stateptr->display, 0, 256 * 128 * sizeof (guint32));
- for (i = 0; i < 256; i++) {
+ memset (stateptr->display, 0, scope_width * scope_height * sizeof (guint32));
+ for (i = 0; i < convolver_small; i++) {
foo = thisEq[i] + (stateptr->avgEq[i] >> 1);
stateptr->avgEq[i] = foo;
if (foo < 0)
diff --git a/gst/monoscope/monoscope.h b/gst/monoscope/monoscope.h
index 8e7d75913..3e79fe49d 100644
--- a/gst/monoscope/monoscope.h
+++ b/gst/monoscope/monoscope.h
@@ -4,21 +4,24 @@
#include <glib.h>
#include "convolve.h"
+#define convolver_depth 8
+#define convolver_small (1 << convolver_depth)
+#define convolver_big (2 << convolver_depth)
#define scope_width 256
#define scope_height 128
struct monoscope_state {
- gint16 copyEq[CONVOLVE_BIG];
- int avgEq[CONVOLVE_SMALL]; /* a running average of the last few. */
- int avgMax; /* running average of max sample. */
- guint32 display[(scope_width + 1) * (scope_height + 1)];
+ short copyEq[convolver_big];
+ int avgEq[convolver_small]; /* a running average of the last few. */
+ int avgMax; /* running average of max sample. */
+ guint32 display[scope_width * scope_height];
- convolve_state *cstate;
- guint32 colors[64];
+ convolve_state *cstate;
+ guint32 colors[64];
};
struct monoscope_state * monoscope_init (guint32 resx, guint32 resy);
-guint32 * monoscope_update (struct monoscope_state * stateptr, gint16 data [512]);
+guint32 * monoscope_update (struct monoscope_state * stateptr, gint16 data [convolver_big]);
void monoscope_close (struct monoscope_state * stateptr);
#endif