Index: docs/architecture.doxi
===================================================================
--- docs/architecture.doxi	(revision 4369)
+++ docs/architecture.doxi	(working copy)
@@ -112,6 +112,13 @@ of the lowercase letters 'a'-'z', the di
 	0.5 (play sample half as loud, corresponding to a -6dB adjustment) and
 	0.25 (corresponds to a -12dB adjustment). The range of valid volume
 	adjustments is: 0 < volume <= 1.0, any other value will be ignored.
+@item @strong{fine-tune}
+	The fine tune allows to change the speed and thus the pitch at which
+	the sample is replayed in cent. This does not affect the raw/compressed
+	audio data actually stored. The default is 0, which means no fine tune.
+	Examples of valid values are 100, which would pitch the sample up one
+	semitone (100 cents), 1200, which would pitch up the sample one octave
+	and -50 which would pitch the sample half a semitone down.
 @item @strong{gus-patch-envelope} -
 	Contains the envelope points for a GUS Patch envelope.
 @done
Index: bse/gslwaveosc.c
===================================================================
--- bse/gslwaveosc.c	(revision 4369)
+++ bse/gslwaveosc.c	(working copy)
@@ -250,7 +250,7 @@ gsl_wave_osc_set_filter (GslWaveOscData 
   if (UNLIKELY (!wosc->config.lookup_wchunk))
     return;
 
-  wosc->step_factor = zero_padding * wosc->wchunk->mix_freq;
+  wosc->step_factor = zero_padding * wosc->wchunk->mix_freq * wosc->wchunk->fine_tune_factor;
   wosc->step_factor /= wosc->wchunk->osc_freq * wosc->mix_freq;
   step = wosc->step_factor * play_freq;
   istep = step * (FRAC_MASK + 1.) + 0.5;
Index: bse/ChangeLog
===================================================================
--- bse/ChangeLog	(revision 4369)
+++ bse/ChangeLog	(working copy)
@@ -1,3 +1,19 @@
+Fri Aug 24 19:09:36 2007  Stefan Westerfeld  <stefan@space.twc.de>
+
+	* bsemathsignal.[hc]: Implemented bse_fine_tune_factor, which is
+	similar to bse_cent_factor, but accepts arbitary doubles as input
+	because it doesn't use a table internally.
+
+	* gsldatahandle.[hc]: Implemented gsl_data_handle_fine_tune, which
+	returns a fine tuning measured in cent ("fine-tune" xinfo).
+
+	* gslwavechunk.[hc]: Cache the fine tune factor here, so that
+	GslWaveOsc can access it quickly.
+
+	* gslwaveosc.c (gsl_wave_osc_set_filter): Take fine tune factor of
+	the chunk into account for step computation (and thus for filter
+	computation).
+
 Sat Aug 18 00:15:22 2007  Stefan Westerfeld  <stefan@space.twc.de>
 
 	* bsecore.idl: Include ~/beast/plugins in the default plugin search
Index: bse/gsldatahandle.c
===================================================================
--- bse/gsldatahandle.c	(revision 4369)
+++ bse/gsldatahandle.c	(working copy)
@@ -305,6 +305,19 @@ gsl_data_handle_volume (GslDataHandle *d
   return f;
 }
 
+gfloat
+gsl_data_handle_fine_tune (GslDataHandle *dhandle)
+{
+  g_return_val_if_fail (dhandle != NULL, 0);
+  g_return_val_if_fail (dhandle->open_count > 0, 0);
+  
+  GSL_SPIN_LOCK (&dhandle->mutex);
+  gfloat f = bse_xinfos_get_float (dhandle->setup.xinfos, "fine-tune");
+  GSL_SPIN_UNLOCK (&dhandle->mutex);
+  
+  return f;
+}
+
 const gchar*
 gsl_data_handle_name (GslDataHandle *dhandle)
 {
Index: bse/gsldatahandle.h
===================================================================
--- bse/gsldatahandle.h	(revision 4369)
+++ bse/gsldatahandle.h	(working copy)
@@ -80,6 +80,7 @@ guint		  gsl_data_handle_bit_depth	    (
 gfloat		  gsl_data_handle_mix_freq	    (GslDataHandle	  *data_handle);
 gfloat		  gsl_data_handle_osc_freq	    (GslDataHandle	  *data_handle);
 gfloat            gsl_data_handle_volume            (GslDataHandle        *data_handle);
+gfloat            gsl_data_handle_fine_tune         (GslDataHandle        *data_handle);
 const gchar*	  gsl_data_handle_name		    (GslDataHandle	  *data_handle);
 int64		  gsl_data_handle_read		    (GslDataHandle	  *data_handle,
 						     int64		   value_offset,
Index: bse/bsemathsignal.c
===================================================================
--- bse/bsemathsignal.c	(revision 4369)
+++ bse/bsemathsignal.c	(working copy)
@@ -213,6 +213,22 @@ static const double cent_table201[100 + 
 };
 const double * const bse_cent_table = cent_table201 + 100;
 
+/**
+ * @param fine_tune	fine tuning in cent
+ * @return		a factor corresponding to this
+ *
+ * This function computes a factor which corresponds to a given fine tuning in
+ * cent.  The result can be used as factor for the frequency or the play speed.
+ * It is similar to the bse_cent_factor macro; however, it doesn't use a table
+ * internally, so the input is not limited in any way (i.e. 777.777 is a valid
+ * fine_tune argument). However, it is computationally more expensive.
+ */
+double
+bse_fine_tune_factor (double fine_tune)
+{
+  return exp (fine_tune * BSE_LN_2_POW_1_DIV_1200_d);
+}
+
 
 /* --- musical tuning systems --- */
 #define SCALED_INTERVAL(scale, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12)       \
Index: bse/bsemathsignal.h
===================================================================
--- bse/bsemathsignal.h	(revision 4369)
+++ bse/bsemathsignal.h	(working copy)
@@ -402,6 +402,8 @@ double        bse_transpose_factor      
 extern const double * const bse_cent_table;
 #define	bse_cent_factor(index /* -100..+100 */)		(bse_cent_table[index])
 
+double  bse_fine_tune_factor (double fine_tune);
+
 /* --- implementation details --- */
 static inline double  G_GNUC_CONST
 bse_approx_atan1 (register double x)
Index: bse/gslwavechunk.c
===================================================================
--- bse/gslwavechunk.c	(revision 4369)
+++ bse/gslwavechunk.c	(working copy)
@@ -18,6 +18,7 @@
 #include "bsemain.h"
 #include "gslcommon.h"
 #include "gsldatahandle.h"
+#include "bsemathsignal.h"
 #include <string.h>
 
 
@@ -638,7 +639,8 @@ gsl_wave_chunk_new (GslDataCache   *dcac
   wchunk->open_count = 0;
   wchunk->mix_freq = mix_freq;
   wchunk->osc_freq = osc_freq;
-  wchunk->volume_adjust = 0.0;  /* will be set in gsl_wave_chunk_open */
+  wchunk->volume_adjust = 0.0;	    /* will be set in gsl_wave_chunk_open */
+  wchunk->fine_tune_factor = 0.0;   /* will be set in gsl_wave_chunk_open */
   wchunk->requested_loop_type = loop_type;
   wchunk->requested_loop_first = loop_first;
   wchunk->requested_loop_last = loop_last;
@@ -697,6 +699,7 @@ gsl_wave_chunk_open (GslWaveChunk *wchun
       wchunk->length *= wchunk->n_channels;
       wchunk->n_pad_values = BSE_CONFIG (wave_chunk_padding) * wchunk->n_channels;
       wchunk->volume_adjust = gsl_data_handle_volume (wchunk->dcache->dhandle);
+      wchunk->fine_tune_factor = bse_fine_tune_factor (gsl_data_handle_fine_tune (wchunk->dcache->dhandle));
       gsl_data_cache_open (wchunk->dcache);
       gsl_data_handle_close (wchunk->dcache->dhandle);
       g_return_val_if_fail (wchunk->dcache->padding >= wchunk->n_pad_values, BSE_ERROR_INTERNAL);
@@ -751,6 +754,7 @@ gsl_wave_chunk_close (GslWaveChunk *wchu
   wchunk->leave_end_norm = 0;
   wchunk->tail_start_norm = 0;
   wchunk->volume_adjust = 0.0;
+  wchunk->fine_tune_factor = 0.0;
   gsl_wave_chunk_unref (wchunk);
 }
 
Index: bse/gslwavechunk.h
===================================================================
--- bse/gslwavechunk.h	(revision 4369)
+++ bse/gslwavechunk.h	(working copy)
@@ -73,9 +73,10 @@ struct _GslWaveChunk
   guint           ref_count;
   guint           open_count;
   /* cached data handle setup */
-  gfloat         mix_freq;      /* recorded with mix_freq */
-  gfloat         osc_freq;      /* while oscillating at osc_freq */
-  gdouble        volume_adjust;	/* cache of dhandle->xinfo["volume"], only valid when opened */
+  gfloat         mix_freq;	    /* recorded with mix_freq */
+  gfloat         osc_freq;	    /* while oscillating at osc_freq */
+  gdouble        volume_adjust;	    /* cache of dhandle->xinfo["volume"], only valid when opened */
+  gdouble        fine_tune_factor;  /* cached factor from dhandle->xinfo["fine-tune"], valid when opened */
 };
 struct _GslWaveChunkBlock
 {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 4369)
+++ ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+Fri Aug 24 19:09:08 2007  Stefan Westerfeld  <stefan@space.twc.de>
+
+	* docs/architecture.doxi: Documented the new "fine-tune" xinfo for
+	bsewave files.
+
 Thu Aug 23 15:17:57 2007  Stefan Westerfeld  <stefan@space.twc.de>
 
 	* tools/bsewavetool.cc: Replaced global -k option by --skip-errors,
