r4105 - trunk/bse
- From: stw svn gnome org
- To: svn-commits-list gnome org
- Subject: r4105 - trunk/bse
- Date: Sun, 26 Nov 2006 10:50:36 -0500 (EST)
Author: stw
Date: 2006-11-26 10:50:26 -0500 (Sun, 26 Nov 2006)
New Revision: 4105
Modified:
trunk/bse/ChangeLog
trunk/bse/Makefile.am
trunk/bse/bsedatahandle-fir.cc
trunk/bse/gsldatahandle.h
Log:
Sun Nov 26 16:32:00 2006 Stefan Westerfeld <stefan space twc de>
* Makefile.am: Added bsedatahandle-fir.cc.
* gsldatahandle.h:
* bsedatahandle-fir.cc: Moved highpass handle here from
../tools/bseloopfuncs.[hc].
Modified: trunk/bse/ChangeLog
===================================================================
--- trunk/bse/ChangeLog 2006-11-26 14:56:29 UTC (rev 4104)
+++ trunk/bse/ChangeLog 2006-11-26 15:50:26 UTC (rev 4105)
@@ -1,7 +1,15 @@
+Sun Nov 26 16:32:00 2006 Stefan Westerfeld <stefan space twc de>
+
+ * Makefile.am: Added bsedatahandle-fir.cc.
+
+ * gsldatahandle.h:
+ * bsedatahandle-fir.cc: Moved highpass handle here from
+ ../tools/bseloopfuncs.[hc].
+
Sun Nov 26 15:51:39 2006 Stefan Westerfeld <stefan space twc de>
- * bsedatahandle-fir.cc: svn copy from ../bseloopfuncs.c: prepare for
- moving highpass handle here.
+ * bsedatahandle-fir.cc: svn copy from ../tools/bseloopfuncs.c: prepare
+ for moving highpass handle here.
Wed Nov 22 21:40:17 2006 Tim Janik <timj gtk org>
Modified: trunk/bse/Makefile.am
===================================================================
--- trunk/bse/Makefile.am 2006-11-26 14:56:29 UTC (rev 4104)
+++ trunk/bse/Makefile.am 2006-11-26 15:50:26 UTC (rev 4105)
@@ -89,7 +89,7 @@
bsenote.c bsemidifile.c bseblockutils.cc \
bsecxxvalue.cc bsecxxutils.cc bsecxxbase.cc bsecxxclosure.cc \
bsecxxarg.cc bsecxxmodule.cc bsecxxplugin.cc bseloader.c \
- bseresampler.cc bsedatahandle-resample.cc \
+ bseresampler.cc bsedatahandle-resample.cc bsedatahandle-fir.cc \
bseloader-aiff.c bseloader-guspatch.cc bseloader-oggvorbis.c bseloader-bsewave.c \
bseloader-mad.c bseloader-wav.c \
)
Modified: trunk/bse/bsedatahandle-fir.cc
===================================================================
--- trunk/bse/bsedatahandle-fir.cc 2006-11-26 14:56:29 UTC (rev 4104)
+++ trunk/bse/bsedatahandle-fir.cc 2006-11-26 15:50:26 UTC (rev 4105)
@@ -16,26 +16,14 @@
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
-#include "bseloopfuncs.h"
-#include <bse/gsldatacache.h>
-#include <bse/gslfilter.h>
-#include <complex.h>
+#include "gsldatahandle.h"
+#include "gsldatautils.h"
+#include "gslfilter.h"
+#include <complex>
#include <string.h>
#include <stdio.h>
#include <math.h>
-typedef struct {
- gdouble score;
- GslLong loop_start;
- GslLong loop_length;
-} LoopEntry;
-typedef struct {
- guint max_entries;
- guint n_entries;
- gdouble worst_score;
- LoopEntry entries[1]; /* flexible array */
-} LoopStack;
-
/*
* 0db ---------- __________
* /
@@ -122,7 +110,19 @@
}
}
-GslDataHandle*
+/*
+ * __________
+ * /
+ * /
+ * /
+ * _____/
+ * |
+ * cutoff_freq
+ *
+ * @cutoff_freq: cutoff frequency in Hz in intervall [0..SR/2]
+ * @order: number of filter coefficients
+ */
+extern "C" GslDataHandle*
gsl_data_handle_new_fir_highpass (GslDataHandle *src_handle,
gdouble cutoff_freq,
guint order)
@@ -163,903 +163,3 @@
gsl_data_handle_unref (mhandle);
return dhandle;
}
-
-static gdouble
-score_headloop (GslDataHandle *dhandle,
- const gfloat *ls, /* loop start */
- GslLong ll, /* loop length */
- GslLong cl, /* compare area length */
- gdouble max_score)
-{
- GslLong nl = cl / ll; /* number of full loop comparisons */
- GslLong rl = cl - nl * ll; /* fraction of last comparison */
- const gfloat *c = ls + ll; /* compare area start */
- const gfloat *p, *le = ls + ll;
- gdouble score = 0;
-
- /* compute score for loop repeated over comparison area
- * .......|##########|-------------------------|......
- * ls c c+cl
- */
-
- while (nl--)
- {
- p = ls;
- while (p < le)
- {
- gdouble tmp = *p++ - *c++;
- GSL_GCC_PREFETCH (p);
- GSL_GCC_PREFETCH (c);
- score += tmp * tmp;
- }
- if (score > max_score)
- return score;
- }
- le = ls + rl;
- p = ls;
- while (p < le)
- {
- gdouble tmp = *p++ - *c++;
- GSL_GCC_PREFETCH (p);
- GSL_GCC_PREFETCH (c);
- score += tmp * tmp;
- }
- return score;
-}
-
-static gdouble
-score_tailloop (GslDataHandle *dhandle,
- const gfloat *cs, /* compare area start */
- GslLong cl, /* compare area length */
- GslLong ll, /* loop length */
- gdouble max_score)
-{
- GslLong nl = cl / ll; /* number of full loop comparisons */
- GslLong rl = cl - nl * ll; /* fraction of last comparison */
- const gfloat *ls = cs + cl; /* loop start */
- const gfloat *le = ls + ll;
- const gfloat *p, *c = cs;
- gdouble score = 0;
-
- /* compute score for loop repeated over comparison area
- * .......|-------------------------|##########|......
- * c ls le
- */
-
- p = ls + ll - rl;
- while (p < le)
- {
- gdouble tmp = *p++ - *c++;
- GSL_GCC_PREFETCH (p);
- GSL_GCC_PREFETCH (c);
- score += tmp * tmp;
- }
- while (nl--)
- {
- if (score > max_score)
- return score;
- p = ls;
- while (p < le)
- {
- gdouble tmp = *p++ - *c++;
- GSL_GCC_PREFETCH (p);
- GSL_GCC_PREFETCH (c);
- score += tmp * tmp;
- }
- }
- return score;
-}
-
-gboolean
-gsl_data_find_loop5 (GslDataHandle *dhandle,
- GslDataLoopConfig *config,
- gpointer pdata,
- GslProgressFunc pfunc)
-{
- GslLong bstart, blength, min_llength, max_llength, i, dhandle_n_values, clength, pcount, score_pcount = 0;
- GslLong frame = 441; // FIXME: need assertion for frame vs. block length
- GslProgressState pstate = gsl_progress_state (pdata, pfunc, 1);
- GslDataPeekBuffer pbuf = { +1, };
- gdouble pdist, fcenter, bfrac;
- guint apoints;
- gfloat *block;
- gboolean found_loop = FALSE;
-
- g_return_val_if_fail (dhandle != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
- g_return_val_if_fail (frame <= config->block_start, FALSE);
- config->n_details = 0;
-
- /* check out data handle */
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return FALSE;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
-
- /* confine parameters */
- bstart = CLAMP (config->block_start, 0, dhandle_n_values - 1);
- if (config->block_length < 0)
- blength = dhandle_n_values - bstart - frame;
- else
- blength = MIN (dhandle_n_values - bstart - frame, config->block_length);
- if (blength < 4)
- return FALSE;
-
- /* determine boundaries */
- max_llength = blength / CLAMP (config->repetitions, 2, blength);
- min_llength = MAX (frame + 1, config->min_loop);
- if (min_llength > max_llength)
- return FALSE;
- /* determine frame distances */
- apoints = CLAMP (config->analysis_points, 1, blength / 2 - 1);
- bfrac = blength / (apoints + 1.0);
- /* length of comparison area */
- clength = blength / 2;
-
- /* provide fully cached area for comparisons */
- block = g_new (gfloat, dhandle_n_values);
- for (i = 0; i < dhandle_n_values; i++)
- block[i] = gsl_data_handle_peek_value (dhandle, i, &pbuf);
-
- /* upper boundary for amount of comparisons */
- pdist = apoints * (max_llength + 1 - min_llength);
- pcount = 0;
- config->score = G_MAXDOUBLE;
-
- /* loop over the centers of all loops */
- for (fcenter = bstart + bfrac; fcenter + 1.0 < bstart + blength; fcenter += bfrac)
- {
- GslLong ipp; // llength;
- /* loop over all loop lengths */
- // for (llength = min_llength; llength <= max_llength; llength++)
- for (ipp = min_llength; ipp <= max_llength - min_llength; ipp++)
- {
- /* for better load balancing, we do simple size alterations and don't loop
- * from min to max loop length but loop from both ends in turn (ipp -> llength)
- */
- GslLong llength = ipp & 1 ? max_llength - ipp / 2 : min_llength + ipp / 2;
- GslLong hstart, hlength, tstart, tlength;
- /* determine loop center as 0-relative position */
- GslLong lstart = fcenter - 0.5;
- /* offset loop around center */
- lstart -= (llength - 1) >> 1;
- /* update progress (inner loop) counter */
- pcount++;
- /* confine to block boundaries */
- if (lstart < bstart || lstart + llength > bstart + blength)
- continue;
- /* center head/tail comparison areas around loop */
- hstart = lstart - clength / 2;
- hlength = clength / 2;
- tstart = lstart + llength;
- tlength = clength / 2;
- /* shift head/tail if either exceeds boundaries */
- if (hstart < bstart)
- {
- GslLong diff = bstart - hstart;
- hstart += diff;
- hlength -= diff;
- tlength += diff;
- }
- else if (tstart + tlength > bstart + blength)
- {
- GslLong diff = tstart + tlength - bstart - blength;
- tlength -= diff;
- hstart -= diff;
- hlength += diff;
- }
- /* accumulate score */
- double score = 0, score1 = 0, score2 = 0;
- double human_size = 1e6;
- double score1_weight = human_size / (2.0 * frame);
- double score2_weight = human_size / (1.0 * tlength + hlength);
-
- /* compute proximity score */
- score1 = score_tailloop (dhandle, block + lstart - frame, frame, llength,
- (config->score - score) / score1_weight);
- score = score1 * score1_weight + score2 * score2_weight;
- score1 += score_headloop (dhandle, block + lstart, llength, frame,
- (config->score - score) / score1_weight);
- score = score1 * score1_weight + score2 * score2_weight;
- /* loop comparision score */
- score2 = score_headloop (dhandle, block + lstart, llength, tlength,
- (config->score - score) / score2_weight);
- score = score1 * score1_weight + score2 * score2_weight;
- score2 += score_tailloop (dhandle, block + hstart, hlength, llength,
- (config->score - score) / score2_weight);
- score = score1 * score1_weight + score2 * score2_weight;
-
- /* apply score */
- if (score < config->score)
- {
- config->loop_start = lstart;
- config->loop_length = llength;
- config->score = score;
- config->n_details = 2;
- config->detail_names[0] = "score1 (proximity score)";
- config->detail_names[1] = "score2 (loop comparision)";
- config->detail_scores[0] = score1 * score1_weight;
- config->detail_scores[1] = score2 * score2_weight;
- score_pcount = pcount;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, pcount * 100.0 / pdist, "score:%+g len:%ld (pos:%6lu len=%ld)",
- config->score, config->loop_length, lstart, llength);
- }
- }
- gsl_progress_wipe (&pstate);
- g_printerr (" LOOP: %6llu - %6llu [%6llu] (block: %6llu - %6llu [%6llu]) (score:%+g at:%5.1f%%)\n",
- config->loop_start, config->loop_start + config->loop_length, config->loop_length,
- bstart, bstart + blength, blength,
- config->score, score_pcount * 100.0 / pdist);
-
- /* cleanups */
- g_free (block);
- gsl_data_handle_close (dhandle);
-
- return found_loop;
-}
-
-gboolean
-gsl_data_find_loop4 (GslDataHandle *dhandle,
- GslDataLoopConfig *config,
- gpointer pdata,
- GslProgressFunc pfunc)
-{
- GslLong bstart, blength, min_llength, max_llength, i, dhandle_n_values, clength, llength, pcount, score_pcount = 0;
- GslProgressState pstate = gsl_progress_state (pdata, pfunc, 1);
- GslDataPeekBuffer pbuf = { +1, };
- gdouble pdist, fcenter, bfrac;
- gfloat *bstart_block;
- const gfloat *block;
- gboolean found_loop = FALSE;
-
- g_return_val_if_fail (dhandle != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
- config->n_details = 0;
-
- /* check out data handle */
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return FALSE;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
-
- /* confine parameters */
- bstart = CLAMP (config->block_start, 0, dhandle_n_values - 1);
- if (config->block_length < 0)
- blength = dhandle_n_values - bstart;
- else
- blength = MIN (dhandle_n_values - bstart, config->block_length);
- if (blength < 4)
- return FALSE;
-
- /* determine boundaries */
- max_llength = blength / CLAMP (config->repetitions, 2, blength);
- min_llength = MAX (1, config->min_loop);
- if (min_llength > max_llength)
- return FALSE;
- /* determine frame distances */
- bfrac = blength / (CLAMP (config->analysis_points, 1, blength / 2 - 1) + 1.0);
- /* length of comparison area */
- clength = blength / 2;
-
- /* provide fully cached area for comparisons */
- bstart_block = g_new (gfloat, blength);
- for (i = 0; i < blength; i++)
- bstart_block[i] = gsl_data_handle_peek_value (dhandle, bstart + i, &pbuf);
- block = bstart_block - bstart;
-
- /* upper boundary for amount of comparisons */
- pdist = (blength / bfrac + 0.5) * (max_llength + 1 - min_llength);
- pcount = 0;
- config->score = G_MAXDOUBLE;
-
- /* loop over the centers of all loops */
- for (fcenter = bstart + bfrac; fcenter + 1.0 < bstart + blength; fcenter += bfrac)
- /* loop over all loop lengths */
- for (llength = min_llength; llength <= max_llength; llength += 1)
- {
- GslLong hstart, hlength, tstart, tlength;
- gdouble score = 0;
- /* determine loop center as 0-relative position */
- GslLong lstart = fcenter - 0.5;
- /* offset loop around center */
- lstart -= (llength - 1) >> 1;
- /* update progress (inner loop) counter */
- pcount++;
- /* confine to block boundaries */
- if (lstart < bstart || lstart + llength > bstart + blength)
- break;
- /* center head/tail comparison areas around loop */
- hstart = lstart - clength / 2;
- hlength = clength / 2;
- tstart = lstart + llength;
- tlength = clength / 2;
- /* shift head/tail if either exceeds boundaries */
- if (hstart < bstart)
- {
- GslLong diff = bstart - hstart;
- hstart += diff;
- hlength -= diff;
- tlength += diff;
- }
- else if (tstart + tlength > bstart + blength)
- {
- GslLong diff = tstart + tlength - bstart - blength;
- tlength -= diff;
- hstart -= diff;
- hlength += diff;
- }
- /* accumulate score */
- score += score_headloop (dhandle, block + lstart, llength, tlength, config->score);
- score += score_tailloop (dhandle, block + hstart, hlength, llength, config->score - score);
- /* apply score */
- if (score < config->score)
- {
- config->loop_start = lstart;
- config->loop_length = llength;
- config->score = score;
- score_pcount = pcount;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, pcount * 100.0 / pdist, "score:%+g len:%ld (pos:%6lu len=%ld)",
- config->score, config->loop_length, lstart, llength);
- }
- gsl_progress_wipe (&pstate);
- g_printerr (" LOOP: %6llu - %6llu [%6llu] (block: %6llu - %6llu [%6llu]) (score:%+g at:%5.1f%%)\n",
- config->loop_start, config->loop_start + config->loop_length, config->loop_length,
- bstart, bstart + blength, blength,
- config->score, score_pcount * 100.0 / pdist);
-
- /* cleanups */
- g_free (bstart_block);
- gsl_data_handle_close (dhandle);
-
- return found_loop;
-}
-
-gboolean
-gsl_data_find_loop3 (GslDataHandle *dhandle,
- GslDataLoopConfig *config,
- gpointer pdata,
- GslProgressFunc pfunc)
-{
- GslProgressState pstate = gsl_progress_state (pdata, pfunc, 4);
- GslDataPeekBuffer pbuf = { +1, };
- GslLong minll, maxll, i, dhandle_n_values, pcount;
- gfloat *sp, *ep, *cstart, *block;
- gdouble pdist;
- gboolean found_loop = FALSE;
-
- g_return_val_if_fail (dhandle != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
- config->n_details = 0;
-
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return FALSE;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
- config->block_start = CLAMP (config->block_start, 0, dhandle_n_values - 1);
- if (config->block_length < 0)
- config->block_length = dhandle_n_values - config->block_start;
- else
- config->block_length = MIN (config->block_length, dhandle_n_values - config->block_start);
- if (config->block_length < 2)
- return FALSE;
- if (config->repetitions != CLAMP (config->repetitions, 2, config->block_length))
- return FALSE;
- /* current implementation supports just repetitions == 2 */
- g_return_val_if_fail (config->repetitions == 2, FALSE);
-
- /* provide fully cached area for comparisons */
- block = g_new (gfloat, config->block_length);
- for (i = 0; i < config->block_length; i++)
- block[i] = gsl_data_handle_peek_value (dhandle, config->block_start + i, &pbuf);
-
- /* test every possible loop size at every possible position */
- maxll = config->block_length / 2;
- minll = maxll * 0.91;
- g_return_val_if_fail (maxll > minll, FALSE); // FIXME
- cstart = block + config->block_length / 2;
- config->score = G_MAXDOUBLE;
- pcount = 0, pdist = (maxll * 1.0 - minll * 1.0 + 2.0) * (maxll * 1.0 - minll * 1.0 + 1.0) / 2.;
- g_printerr ("pdist: %f\n", pdist);
- for (sp = block; sp < cstart - minll; sp++)
- for (ep = sp + minll; ep < cstart; ep++)
- {
- gdouble score = score_headloop (dhandle, sp, ep - sp, config->block_length / 2, config->score);
- if (score <= config->score)
- {
- config->loop_start = sp - block;
- config->loop_length = ep - sp;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "score:%+g (pos:%6lu)", config->score, sp - block);
- // g_printerr ("processed: %7.3f (score:%+g) \r", ++pcount * 100.0 / pdist, config->score);
- }
-
- g_free (block);
- gsl_data_handle_close (dhandle);
- return found_loop;
-}
-
-gboolean
-gsl_data_find_loop2 (GslDataHandle *dhandle,
- GslDataLoopConfig *config,
- gpointer pdata,
- GslProgressFunc pfunc)
-{
- GslProgressState pstate = gsl_progress_state (pdata, pfunc, 4);
- GslDataPeekBuffer pbuf = { +1, };
- GslLong minll, maxll, i, dhandle_n_values, pcount, ll;
- gfloat *sp, *ep, *cstart, *block;
- gdouble pdist;
- gboolean found_loop = FALSE;
-
- g_return_val_if_fail (dhandle != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
- config->n_details = 0;
-
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return FALSE;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
- config->block_start = CLAMP (config->block_start, 0, dhandle_n_values - 1);
- if (config->block_length < 0)
- config->block_length = dhandle_n_values - config->block_start;
- else
- config->block_length = MIN (config->block_length, dhandle_n_values - config->block_start);
- if (config->block_length < 2)
- return FALSE;
- if (config->repetitions != CLAMP (config->repetitions, 2, config->block_length))
- return FALSE;
- /* current implementation supports just repetitions == 2 */
- g_return_val_if_fail (config->repetitions == 2, FALSE);
-
- /* provide fully cached area for comparisons */
- block = g_new (gfloat, config->block_length);
- for (i = 0; i < config->block_length; i++)
- block[i] = gsl_data_handle_peek_value (dhandle, config->block_start + i, &pbuf);
-
- goto print_sizes;
-
- /* find best loop size at one position */
- maxll = config->block_length / 2;
- minll = 1;
- g_return_val_if_fail (maxll > minll, FALSE); // FIXME
- cstart = block + config->block_length / 2;
- config->score = G_MAXDOUBLE;
- pcount = 0, pdist = (maxll * 1.0 - minll * 1.0 + 2.0) * (maxll * 1.0 - minll * 1.0 + 1.0) / 2.;
- sp = block;
- for (ep = sp + minll; ep < cstart; ep++)
- {
- gdouble score = score_headloop (dhandle, sp, ep - sp, config->block_length / 2, config->score);
- if (score <= config->score)
- {
- config->loop_start = sp - block;
- config->loop_length = ep - sp;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "score:%+g (pos:%6lu)", config->score, sp - block);
- }
- gsl_progress_wipe (&pstate);
- ll = config->loop_length;
- g_printerr ("loop size: %llu\n", ll);
-
- /* test every possible position */
- minll = ll;
- maxll = ll + 1;
- g_return_val_if_fail (maxll > minll, FALSE); // FIXME
- cstart = block + config->block_length / 2;
- config->score = G_MAXDOUBLE;
- pcount = 0, pdist = (maxll * 1.0 - minll * 1.0 + 2.0) * (maxll * 1.0 - minll * 1.0 + 1.0) / 2.;
- g_printerr ("pdist: %f\n", pdist);
- for (sp = block; sp < cstart - minll; sp++)
- {
- ep = sp + minll;
- {
- gdouble score = score_headloop (dhandle, sp, ep - sp, config->block_length / 2, G_MAXDOUBLE);
- g_print ("%u %.17g\n", sp - block, score);
- continue;
- if (score <= config->score)
- {
- config->loop_start = sp - block;
- config->loop_length = ep - sp;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "score:%+g (pos:%6lu)", config->score, sp - block);
- }
- }
-
- G_BREAKPOINT ();
- print_sizes:
-
- /* test every possible loop size */
- maxll = config->block_length / 2;
- minll = 1;
- g_return_val_if_fail (maxll > minll, FALSE); // FIXME
- cstart = block + config->block_length / 2;
- config->score = G_MAXDOUBLE;
- pcount = 0, pdist = (maxll * 1.0 - minll * 1.0 + 2.0) * (maxll * 1.0 - minll * 1.0 + 1.0) / 2.;
- g_printerr ("pdist: %f\n", pdist);
- for (sp = block + 99999; sp < cstart - minll; sp++)
- {
- for (ep = sp + minll; ep < cstart; ep++)
- {
- gdouble score = score_headloop (dhandle, sp, ep - sp, config->block_length / 2, config->score);
- g_print ("%u %.17g\n", ep - sp, score);
- continue;
- if (score <= config->score)
- {
- config->loop_start = sp - block;
- config->loop_length = ep - sp;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "score:%+g (pos:%6lu)", config->score, sp - block);
- }
- G_BREAKPOINT ();
- }
-
- g_free (block);
- gsl_data_handle_close (dhandle);
- return found_loop;
-}
-
-static inline gdouble
-dcache_headloop_score (GslDataCache *dcache,
- GslLong lstart, /* loop start (reaches till bstart) */
- GslLong cstart, /* compare area start sample */
- GslLong clength, /* compare area length */
- gdouble max_score, /* no need to score beyond this */
- GslDataCacheNode **lnp,
- GslDataCacheNode **cnp,
- gboolean weighted)
-{
- gsize node_size = GSL_DATA_CACHE_NODE_SIZE (dcache);
- GslDataCacheNode *lnode = *lnp, *cnode = *cnp;
- gdouble wmax = clength, score = 0.0;
- GslLong i = 0, loop_length = cstart - lstart;
-
- /* compute score for loop repeated over comparison area
- * .......|##########|-------------------------|......
- * loopstart cstart (cstart+clength)
- */
-
- while (i < clength)
- {
- GslLong cdiff, ldiff, clen, llen, k, l = i % loop_length;
- gfloat *cb, *lb; /* base pointer */
- if (lnode->offset > lstart + l || lstart + l >= lnode->offset + node_size)
- {
- gsl_data_cache_unref_node (dcache, lnode);
- lnode = *lnp = gsl_data_cache_ref_node (dcache, lstart + l, TRUE);
- }
- if (cnode->offset > cstart + i || cstart + i >= cnode->offset + node_size)
- {
- gsl_data_cache_unref_node (dcache, cnode);
- cnode = *cnp = gsl_data_cache_ref_node (dcache, cstart + i, TRUE);
- }
- cdiff = cstart + i - cnode->offset;
- ldiff = lstart + l - lnode->offset;
- clen = MIN (node_size - cdiff, clength - i);
- llen = MIN (node_size - ldiff, loop_length - l);
- cb = cnode->data + cdiff - i;
- lb = lnode->data + ldiff - i;
- if (weighted)
- for (k = i + MIN (llen, clen); i < k; i++)
- {
- gdouble ed = lb[i] - cb[i];
- score += ed * ed * (1.0 - i / wmax);
- }
- else
- for (k = i + MIN (llen, clen); i < k; i++)
- {
- gdouble ed = lb[i] - cb[i];
- score += ed * ed;
- }
- if (score > max_score)
- break;
- }
-
- return score;
-}
-
-gboolean
-gsl_data_find_loop1 (GslDataHandle *dhandle,
- GslDataLoopConfig *config,
- gpointer pdata,
- GslProgressFunc pfunc)
-{
- GslProgressState pstate = gsl_progress_state (pdata, pfunc, 1);
- guint frame = 4410; // FIXME: adjustable value?
- GslLong cstart, clength, j, dhandle_n_values, ls, ll, minll, pcount, maxll, min_loop = frame;
- GslDataCache *dcache;
- GslDataCacheNode *dnode1, *dnode2;
- gdouble pdist;
- gboolean found_loop = FALSE;
-
- g_return_val_if_fail (dhandle != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
- config->n_details = 0;
-
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return FALSE;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
- config->block_start = CLAMP (config->block_start, 0, dhandle_n_values - 1);
- if (config->block_length < 0)
- config->block_length = dhandle_n_values - config->block_start;
- else
- config->block_length = MIN (config->block_length, dhandle_n_values - config->block_start);
- if (config->block_length < 2)
- return FALSE;
- if (config->repetitions != CLAMP (config->repetitions, 2, config->block_length))
- return FALSE;
-
- dcache = gsl_data_cache_new (dhandle, 1);
- gsl_data_cache_open (dcache);
- gsl_data_handle_close (dhandle);
- gsl_data_cache_unref (dcache);
-
- dnode1 = gsl_data_cache_ref_node (dcache, config->block_start, TRUE);
- dnode2 = gsl_data_cache_ref_node (dcache, config->block_start, TRUE);
-
- /* widen loop, keeping it end-aligned to cstart
- * |------------##########|--------------------|......
- * block_start loopstart cstart (cstart+clength)
- */
-
- /* find a good loop length */
- config->score = G_MAXDOUBLE;
- cstart = config->block_start + config->block_length / config->repetitions;
- clength = config->block_length - (cstart - config->block_start);
- pcount = 0, pdist = (cstart - min_loop - config->block_start);
- for (j = config->block_start; j < cstart - min_loop; j++)
- {
- gdouble score = dcache_headloop_score (dcache, j, cstart, clength, config->score, &dnode1, &dnode2, FALSE);
- if (score <= config->score)
- {
- config->loop_start = j;
- config->loop_length = cstart - j;
- config->score = score;
- found_loop = TRUE;
- }
- if (pcount++ % 16 == 0)
- gsl_progress_notify (&pstate, pcount * 100.0 / pdist, "score:%+g", config->score);
- }
- gsl_progress_wipe (&pstate);
- if (!found_loop)
- goto seek_loop_done;
- g_printerr (" lLOOP: %6llu - %6llu [%6llu] (block: %6llu - %6llu [%6llu]) (score:%+g)\n",
- config->loop_start, config->loop_start + config->loop_length, config->loop_length,
- config->block_start, config->block_start + config->block_length, config->block_length,
- config->score);
-
- /* find best loop position */
- ll = config->loop_length;
- minll = ll;
- maxll = ll + 1;
- config->score = G_MAXDOUBLE;
- pcount = 0, pdist = (config->block_length - maxll - frame) * (maxll - minll);
- for (ls = config->block_start; ls + maxll + frame <= config->block_start + config->block_length; ls++)
- {
- /* find best loop length */
- for (ll = minll; ll < maxll; ll++)
- {
- gdouble score = dcache_headloop_score (dcache, ls, ls + ll, frame, config->score, &dnode1, &dnode2, TRUE);
- if (score <= config->score)
- {
- config->loop_start = ls;
- config->loop_length = ll;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "weighted-frame-score:%+g", config->score);
- }
- }
- gsl_progress_wipe (&pstate);
- g_printerr (" pLOOP: %6llu - %6llu [%6llu] (block: %6llu - %6llu [%6llu]) (weighted-frame-score:%+g)\n",
- config->loop_start, config->loop_start + config->loop_length, config->loop_length,
- config->block_start, config->block_start + config->block_length, config->block_length,
- config->score);
-
- /* find best loop length */
- frame = MIN (config->loop_length / 5, 4410 * 7);
- while (frame >= 32) // FIXME
- {
- /* jitter loop length */
- minll = config->loop_length - frame;
- minll = MAX (minll, 1);
- maxll = config->loop_length + frame;
- maxll = MIN (config->block_start + config->block_length - frame,
- config->loop_start + maxll) -
- config->loop_start;
-
- /* find best loop length */
- config->score = G_MAXDOUBLE;
- ls = config->loop_start;
- pcount = 0, pdist = maxll - minll;
- for (ll = minll; ll < maxll; ll++)
- {
- gdouble score = dcache_headloop_score (dcache, ls, ls + ll, frame, config->score, &dnode1, &dnode2, FALSE);
- if (score <= config->score)
- {
- config->loop_start = ls;
- config->loop_length = ll;
- config->score = score;
- found_loop = TRUE;
- }
- gsl_progress_notify (&pstate, ++pcount * 100.0 / pdist, "frame-score:%+g", config->score);
- }
- gsl_progress_wipe (&pstate);
- g_printerr (" sLOOP: %6llu - %6llu [%6llu] (block: %6llu - %6llu [%6llu]) (frame[%d]-score:%+g)\n",
- config->loop_start, config->loop_start + config->loop_length, config->loop_length,
- config->block_start, config->block_start + config->block_length, config->block_length,
- frame, config->score);
- frame /= 2;
- }
-
- seek_loop_done:
-
- gsl_data_cache_unref_node (dcache, dnode1);
- gsl_data_cache_unref_node (dcache, dnode2);
-
- gsl_data_cache_close (dcache);
- return found_loop;
-}
-
-static inline float
-tailloop_score (GslDataCache *dcache,
- const GslDataTailLoop *cfg,
- GslLong loopstart,
- GslLong loopsize,
- gfloat worstscore)
-{
- gsize node_size = GSL_DATA_CACHE_NODE_SIZE (dcache);
- GslLong looppos, i, compare = cfg->pre_loop_compare;
- gfloat score = 0.0;
- GslDataCacheNode *snode, *lnode;
-
- /* compute score for loopsize with compare samples before loop */
- /* -----|-------------------------|-----------------
- * loopstart-compare loopstart
- */
-
- looppos = loopstart - compare;
- while (looppos < loopstart)
- looppos += loopsize;
-
- snode = gsl_data_cache_ref_node (dcache, loopstart - compare, TRUE);
- lnode = gsl_data_cache_ref_node (dcache, looppos, TRUE);
- for (i = loopstart - compare; i < loopstart;)
- {
- GslLong sdiff, ldiff, slen, llen, loop_len, compare_len, j;
- gfloat *sb, *lb;
-
- if (snode->offset > i || i >= snode->offset + node_size)
- {
- gsl_data_cache_unref_node (dcache, snode);
- snode = gsl_data_cache_ref_node (dcache, i, TRUE);
- }
- if (lnode->offset > looppos || looppos >= lnode->offset + node_size)
- {
- gsl_data_cache_unref_node (dcache, lnode);
- lnode = gsl_data_cache_ref_node (dcache, looppos, TRUE);
- }
- sdiff = i - snode->offset;
- ldiff = looppos - lnode->offset;
- slen = node_size - sdiff;
- llen = node_size - ldiff;
- sb = snode->data + sdiff;
- lb = lnode->data + ldiff;
- compare_len = loopstart - i;
- loop_len = loopsize - (looppos - loopstart);
-
- slen = MIN (slen, compare_len);
- llen = MIN (llen, loop_len);
- slen = MIN (slen, llen);
-
- j = slen;
- if (cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_CORRELATION)
- {
- while (j--)
- score += sb[j] * lb[j];
- }
- else
- {
- while (j--)
- {
- gfloat tmp = lb[j] - sb[j];
- score += tmp * tmp;
- }
- if (score > worstscore)
- break;
- }
-
- i += slen;
- looppos += slen;
- if (looppos >= loopstart + loopsize)
- looppos -= loopsize;
- }
- gsl_data_cache_unref_node (dcache, snode);
- gsl_data_cache_unref_node (dcache, lnode);
-
- return score;
-}
-
-gdouble
-gsl_data_find_loop0 (GslDataHandle *dhandle,
- const GslDataTailLoop *cfg,
- GslLong *loop_start_p,
- GslLong *loop_end_p)
-{
- GslDataCache *dcache;
- GslLong perc_bound, cfg_max_loop, dhandle_n_values;
- GslLong perc_count = 0, perc_val = 0;
- GslLong loopsize, bestloopsize = 0;
- gdouble bestscore;
-
- g_return_val_if_fail (dhandle != NULL, 0);
- g_return_val_if_fail (cfg != NULL, 0);
- g_return_val_if_fail (loop_start_p != NULL, 0);
- g_return_val_if_fail (loop_end_p != NULL, 0);
- g_return_val_if_fail (cfg->min_loop >= 1, 0);
-
- if (gsl_data_handle_open (dhandle) != BSE_ERROR_NONE)
- return 0;
- dhandle_n_values = gsl_data_handle_n_values (dhandle);
-
- g_return_val_if_fail (cfg->pre_loop_compare < dhandle_n_values - 1, 0);
- cfg_max_loop = cfg->max_loop < 0 ? dhandle_n_values - 1 - cfg->pre_loop_compare : cfg->max_loop;
- g_return_val_if_fail (cfg_max_loop >= cfg->min_loop, 0);
- g_return_val_if_fail (cfg->pre_loop_compare + cfg_max_loop < dhandle_n_values, 0);
- g_return_val_if_fail (cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_LEAST_SQUARE ||
- cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_CORRELATION, 0);
-
- dcache = gsl_data_cache_new (dhandle, 1);
- gsl_data_cache_open (dcache);
- gsl_data_handle_close (dhandle);
- gsl_data_cache_unref (dcache);
-
- perc_bound = (cfg_max_loop - cfg->min_loop) / 100.0;
-
- /* we try to maximize correlation, but to minimize the error */
- if (cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_CORRELATION)
- bestscore = 0.0;
- else
- bestscore = 1e+14;
-
- for (loopsize = cfg->min_loop; loopsize < cfg_max_loop; loopsize++)
- {
- gdouble score = tailloop_score (dcache, cfg,
- dhandle_n_values - loopsize, loopsize,
- bestscore);
-
- /* we try to maximize correlation, but to minimize the error */
- if ((cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_CORRELATION && score > bestscore) ||
- (cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_LEAST_SQUARE && score < bestscore))
- {
- bestloopsize = loopsize;
- bestscore = score;
- }
- if (++perc_count >= perc_bound)
- {
- perc_count = 0;
- perc_val++;
- g_printerr ("processed %llu%% \r", perc_val);
- }
- }
- g_printerr ("\nbest match (%s): len in samples=%lld, len=%lld, score=%f\n",
- (cfg->cmp_strategy == GSL_DATA_TAIL_LOOP_CMP_CORRELATION) ? "correlation" : "least squares",
- bestloopsize, bestloopsize, bestscore);
-
- *loop_start_p = dhandle_n_values - bestloopsize;
- *loop_end_p = dhandle_n_values - 1;
-
- gsl_data_cache_close (dcache);
-
- /* FIXME: statistics: scan for other extreme points in
- * score[cfg->min_loop..cfg_max_loop]
- */
-
- return bestscore;
-}
Modified: trunk/bse/gsldatahandle.h
===================================================================
--- trunk/bse/gsldatahandle.h 2006-11-26 14:56:29 UTC (rev 4104)
+++ trunk/bse/gsldatahandle.h 2006-11-26 15:50:26 UTC (rev 4105)
@@ -118,6 +118,11 @@
GslDataHandle* bse_data_handle_new_downsample2 (GslDataHandle *src_handle,
int precision_bits); // implemented in bsedatahandle-resample.cc
+GslDataHandle* gsl_data_handle_new_fir_highpass (GslDataHandle *src_handle, // implemented in bsedatahandle-fir.cc
+ gdouble cutoff_freq,
+ guint order);
+
+
/* --- xinfo handling --- */
GslDataHandle* gsl_data_handle_new_add_xinfos (GslDataHandle *src_handle,
gchar **xinfos);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]