r4073 - trunk/bse



Author: stw
Date: 2006-11-13 14:10:36 -0500 (Mon, 13 Nov 2006)
New Revision: 4073

Modified:
   trunk/bse/ChangeLog
   trunk/bse/bsedatahandle-resample.cc
   trunk/bse/bseresampler.hh
   trunk/bse/bseresamplerimpl.hh
Log:
Mon Nov 13 20:05:53 2006  Stefan Westerfeld  <stefan space twc de>

	* bseresamplerimpl.hh: Removed unnecessary delay. The stream delay for
	both, upsampling and downsampling should be truely minimal now.

	* bseresampler.hh: The guarantee that the upsampler delay is even was
	removed from the API. The reason is that we can have a shorter stream
	delay when the upsampler delay is odd.

	* bsedatahandle-resample.cc: Introduced additional delay compensation
	code, because compensating an odd upsampler delay wasn't necessary
	when this code was initially written.


Modified: trunk/bse/ChangeLog
===================================================================
--- trunk/bse/ChangeLog	2006-11-08 22:45:16 UTC (rev 4072)
+++ trunk/bse/ChangeLog	2006-11-13 19:10:36 UTC (rev 4073)
@@ -1,3 +1,16 @@
+Mon Nov 13 20:05:53 2006  Stefan Westerfeld  <stefan space twc de>
+
+	* bseresamplerimpl.hh: Removed unnecessary delay. The stream delay for
+	both, upsampling and downsampling should be truely minimal now.
+
+	* bseresampler.hh: The guarantee that the upsampler delay is even was
+	removed from the API. The reason is that we can have a shorter stream
+	delay when the upsampler delay is odd.
+
+	* bsedatahandle-resample.cc: Introduced additional delay compensation
+	code, because compensating an odd upsampler delay wasn't necessary
+	when this code was initially written.
+
 Wed Nov  8 23:28:05 2006  Stefan Westerfeld  <stefan space twc de>
 
 	* bseresampler.[hc]* bseresamplerimpl.hh: Added coefficient set for

Modified: trunk/bse/bsedatahandle-resample.cc
===================================================================
--- trunk/bse/bsedatahandle-resample.cc	2006-11-08 22:45:16 UTC (rev 4072)
+++ trunk/bse/bsedatahandle-resample.cc	2006-11-13 19:10:36 UTC (rev 4073)
@@ -45,6 +45,7 @@
   vector<float>		m_pcm_data;
   int64			m_frame_size;
   int64                 m_filter_delay;
+  int64                 m_filter_delay_input;
   int64                 m_filter_order;
   bool			m_init_ok;
 
@@ -182,9 +183,20 @@
      * compensate by shifting the input samples to enable seeking, thus the
      * factor 2
      */
-    m_filter_delay = (mode() == BSE_RESAMPLER2_MODE_UPSAMPLE ?
-		      (int) round (m_resamplers[0]->delay() / 2) :
-		      (int) round (m_resamplers[0]->delay() * 2));
+    if (mode() == BSE_RESAMPLER2_MODE_UPSAMPLE)
+      {
+	m_filter_delay = (int) round (m_resamplers[0]->delay());
+
+	// dividing this value may erase half a sample delay (if m_filter_delay is odd)
+	// this half sample delay is compensated on the input
+	m_filter_delay_input = m_filter_delay % 2;
+	m_filter_delay /= 2;
+      }
+    else
+      {
+	m_filter_delay = (int) round (m_resamplers[0]->delay() * 2);
+	m_filter_delay_input = 0;
+      }
     return BSE_ERROR_NONE;
   }
   void
@@ -204,6 +216,11 @@
 	int64  n_values,
 	float *values)
   {
+    /* for odd upsampler delays, shift the read request 1 sample (in addition
+     * to the delay compensation performed in src_read())
+     */
+    voffset += m_filter_delay_input * m_dhandle.setup.n_channels;
+
     int64 frame = voffset / m_pcm_data.size();
     if (frame != m_pcm_frame)
       {

Modified: trunk/bse/bseresampler.hh
===================================================================
--- trunk/bse/bseresampler.hh	2006-11-08 22:45:16 UTC (rev 4072)
+++ trunk/bse/bseresampler.hh	2006-11-13 19:10:36 UTC (rev 4073)
@@ -83,7 +83,7 @@
   virtual guint	      order() const = 0;
   /**
    * Return the delay introduced by the resampler. This delay is guaranteed to
-   * be >= 0.0, and for factor 2 resampling always a multiple of 0.5 (2.0 for
+   * be >= 0.0, and for factor 2 resampling always a multiple of 0.5 (1.0 for
    * upsampling).
    *
    * The return value can also be thought of as index into the output signal,

Modified: trunk/bse/bseresamplerimpl.hh
===================================================================
--- trunk/bse/bseresamplerimpl.hh	2006-11-08 22:45:16 UTC (rev 4072)
+++ trunk/bse/bseresamplerimpl.hh	2006-11-13 19:10:36 UTC (rev 4073)
@@ -295,23 +295,23 @@
   process_4samples_aligned (const float *input /* aligned */,
                             float       *output)
   {
-    const guint H = (ORDER / 2) - 1; /* half the filter length */
+    const guint H = (ORDER / 2); /* half the filter length */
     
-    output[0] = input[H];
-    output[2] = input[H + 1];
-    output[4] = input[H + 2];
-    output[6] = input[H + 3];
+    output[1] = input[H];
+    output[3] = input[H + 1];
+    output[5] = input[H + 2];
+    output[7] = input[H + 3];
     
-    fir_process_4samples_sse (input, &sse_taps[0], ORDER, &output[1], &output[3], &output[5], &output[7]);
+    fir_process_4samples_sse (input, &sse_taps[0], ORDER, &output[0], &output[2], &output[4], &output[6]);
   }
   /* slow convolution */
   void
   process_sample_unaligned (const float *input,
                             float       *output)
   {
-    const guint H = (ORDER / 2) - 1; /* half the filter length */
-    output[0] = input[H];
-    output[1] = fir_process_one_sample<float> (&input[0], &taps[0], ORDER);
+    const guint H = (ORDER / 2); /* half the filter length */
+    output[0] = fir_process_one_sample<float> (&input[0], &taps[0], ORDER);
+    output[1] = input[H];
   }
   void
   process_block_aligned (const float *input,
@@ -371,22 +371,22 @@
                  guint        n_input_samples,
 		 float       *output)
   {
-    unsigned int history_todo = min (n_input_samples, ORDER);
+    const unsigned int history_todo = min (n_input_samples, ORDER - 1);
     
-    copy (input, input + history_todo, &history[ORDER]);
+    copy (input, input + history_todo, &history[ORDER - 1]);
     process_block_aligned (&history[0], history_todo, output);
-    if (n_input_samples >= ORDER)
+    if (n_input_samples > history_todo)
       {
 	process_block_unaligned (input, n_input_samples - history_todo, &output [2 * history_todo]);
         
 	// build new history from new input
-	copy (input + n_input_samples - ORDER, input + n_input_samples, &history[0]);
+	copy (input + n_input_samples - history_todo, input + n_input_samples, &history[0]);
       }
     else
       {
 	// build new history from end of old history
 	// (very expensive if n_input_samples tends to be a lot smaller than ORDER often)
-	g_memmove (&history[0], &history[n_input_samples], sizeof (history[0]) * ORDER);
+	g_memmove (&history[0], &history[n_input_samples], sizeof (history[0]) * (ORDER - 1));
       }
   }
   /**
@@ -400,7 +400,7 @@
   double
   delay() const
   {
-    return order() + 2;
+    return order() - 1;
   }
 };
 
@@ -539,26 +539,26 @@
 	const float       *input_odd = input + 1; /* we process this one with a stepping of 2 */
         
 	const unsigned int n_output_todo = n_input_todo / 2;
-	const unsigned int history_todo = min (n_output_todo, ORDER);
+	const unsigned int history_todo = min (n_output_todo, ORDER - 1);
         
-	copy (input_even, input_even + history_todo, &history_even[ORDER]);
-	deinterleave2 (input_odd, history_todo * 2, &history_odd[ORDER]);
+	copy (input_even, input_even + history_todo, &history_even[ORDER - 1]);
+	deinterleave2 (input_odd, history_todo * 2, &history_odd[ORDER - 1]);
         
 	process_block_aligned <1> (&history_even[0], &history_odd[0], output, history_todo);
-	if (n_output_todo >= ORDER)
+	if (n_output_todo > history_todo)
 	  {
 	    process_block_unaligned<2> (input_even, input_odd, &output[history_todo], n_output_todo - history_todo);
             
-	    // build new history from new input
-	    copy (input_even + n_output_todo - ORDER, input_even + n_output_todo, &history_even[0]);
-	    deinterleave2 (input_odd + n_input_todo - ORDER * 2, ORDER * 2, &history_odd[0]); /* FIXME: can be optimized */
+	    // build new history from new input (here: history_todo == ORDER - 1)
+	    copy (input_even + n_output_todo - history_todo, input_even + n_output_todo, &history_even[0]);
+	    deinterleave2 (input_odd + n_input_todo - history_todo * 2, history_todo * 2, &history_odd[0]); /* FIXME: can be optimized */
 	  }
 	else
 	  {
 	    // build new history from end of old history
 	    // (very expensive if n_output_todo tends to be a lot smaller than ORDER often)
-	    g_memmove (&history_even[0], &history_even[n_output_todo], sizeof (history_even[0]) * ORDER);
-	    g_memmove (&history_odd[0], &history_odd[n_output_todo], sizeof (history_odd[0]) * ORDER);
+	    g_memmove (&history_even[0], &history_even[n_output_todo], sizeof (history_even[0]) * (ORDER - 1));
+	    g_memmove (&history_odd[0], &history_odd[n_output_todo], sizeof (history_odd[0]) * (ORDER - 1));
 	  }
         
 	n_input_samples -= n_input_todo;
@@ -577,7 +577,7 @@
   double
   delay() const
   {
-    return order() / 2 + 0.5;
+    return order() / 2 - 0.5;
   }
 };
 




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]