Added the get functions, some tweaks to the "magic samples".
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 14 Feb 2007 01:12:30 +0000 (01:12 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 14 Feb 2007 01:12:30 +0000 (01:12 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@12463 0101bb08-14d6-0310-b084-bc0e0c8e3800

include/speex/speex_resampler.h
libspeex/resample.c

index d396658..49514a7 100644 (file)
@@ -183,6 +183,15 @@ void speex_resampler_set_rate(SpeexResamplerState *st,
                               int in_rate, 
                               int out_rate);
 
+/** Get the current input/output sampling rates (integer value).
+ * @param st Resampler state
+ * @param in_rate Input sampling rate (integer number of Hz) copied.
+ * @param out_rate Output sampling rate (integer number of Hz) copied.
+ */
+void speex_resampler_get_rate(SpeexResamplerState *st, 
+                              int *in_rate, 
+                              int *out_rate);
+
 /** Set (change) the input/output sampling rates and resampling ratio 
  * (fractional values in Hz supported).
  * @param st Resampler state
@@ -197,6 +206,16 @@ void speex_resampler_set_rate_frac(SpeexResamplerState *st,
                                    int in_rate, 
                                    int out_rate);
 
+/** Get the current resampling ratio. This will be reduced to the least
+ * common denominator.
+ * @param st Resampler state
+ * @param ratio_num Numerator of the sampling rate ratio copied
+ * @param ratio_den Denominator of the sampling rate ratio copied
+ */
+void speex_resampler_get_ratio(SpeexResamplerState *st, 
+                                   int *ratio_num, 
+                                   int *ratio_den);
+
 /** Set (change) the conversion quality.
  * @param st Resampler state
  * @param quality Resampling quality between 0 and 10, where 0 has poor 
@@ -205,6 +224,14 @@ void speex_resampler_set_rate_frac(SpeexResamplerState *st,
 void speex_resampler_set_quality(SpeexResamplerState *st, 
                                  int quality);
 
+/** Get the conversion quality.
+ * @param st Resampler state
+ * @param quality Resampling quality between 0 and 10, where 0 has poor 
+ * quality and 10 has very high quality.
+ */
+void speex_resampler_get_quality(SpeexResamplerState *st, 
+                                 int *quality);
+
 /** Set (change) the input stride.
  * @param st Resampler state
  * @param stride Input stride
@@ -212,6 +239,13 @@ void speex_resampler_set_quality(SpeexResamplerState *st,
 void speex_resampler_set_input_stride(SpeexResamplerState *st, 
                                       int stride);
 
+/** Get the input stride.
+ * @param st Resampler state
+ * @param stride Input stride copied
+ */
+void speex_resampler_get_input_stride(SpeexResamplerState *st, 
+                                      int *stride);
+
 /** Set (change) the output stride.
  * @param st Resampler state
  * @param stride Output stride
@@ -219,6 +253,13 @@ void speex_resampler_set_input_stride(SpeexResamplerState *st,
 void speex_resample_set_output_stride(SpeexResamplerState *st, 
                                       int stride);
 
+/** Get the output stride.
+ * @param st Resampler state copied
+ * @param stride Output stride
+ */
+void speex_resample_get_output_stride(SpeexResamplerState *st, 
+                                      int *stride);
+
 /** Make sure that the first samples to go out of the resamplers don't have 
  * leading zeros. This is only useful before starting to use a newly created 
  * resampler. It is recommended to use that when resampling an audio file, as
index a2fdff0..53782ce 100644 (file)
@@ -83,8 +83,6 @@ void speex_free (void *ptr) {free(ptr);}
 #define IMAX(a,b) ((a) > (b) ? (a) : (b))
 
 
-typedef enum {SPEEX_RESAMPLER_DIRECT_SINGLE=0, SPEEX_RESAMPLER_INTERPOLATE_SINGLE=1} SpeexSincType;
-
 typedef int (*resampler_basic_func)(SpeexResamplerState *, int , const spx_word16_t *, int *, spx_word16_t *, int *);
 
 struct SpeexResamplerState_ {
@@ -116,7 +114,6 @@ struct SpeexResamplerState_ {
          
    int    in_stride;
    int    out_stride;
-   SpeexSincType type;
 } ;
 
 static double kaiser10_table[36] = {
@@ -413,7 +410,6 @@ static void update_filter(SpeexResamplerState *st)
             st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);
          }
       }
-      st->type = SPEEX_RESAMPLER_DIRECT_SINGLE;
       st->resampler_ptr = resampler_basic_direct_single;
       /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
    } else {
@@ -426,7 +422,6 @@ static void update_filter(SpeexResamplerState *st)
       }
       for (i=-4;i<st->oversample*st->filt_len+4;i++)
          st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func);
-      st->type = SPEEX_RESAMPLER_INTERPOLATE_SINGLE;
       st->resampler_ptr = resampler_basic_interpolate_single;
       /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
    }
@@ -561,13 +556,23 @@ static void speex_resampler_process_native(SpeexResamplerState *st, int channel_
    if (st->magic_samples)
    {
       int tmp_in_len;
+      int tmp_magic;
       tmp_in_len = st->magic_samples[channel_index];
       tmp_out_len = *out_len;
       /* FIXME: Need to handle the case where the out array is too small */
       /* magic_samples needs to be set to zero to avoid infinite recursion */
-      st->magic_samples = 0;
+      tmp_magic = st->magic_samples[channel_index];
+      st->magic_samples[channel_index] = 0;
       speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len);
       /*speex_warning_int("extra samples:", tmp_out_len);*/
+      /* If we couldn't process all "magic" input samples, save the rest for next time */
+      if (tmp_in_len < tmp_magic)
+      {
+         int i;
+         st->magic_samples[channel_index] = tmp_magic-tmp_in_len;
+         for (i=0;i<st->magic_samples[channel_index];i++)
+            mem[N-1+i]=mem[N-1+i+tmp_in_len];
+      }
       out += tmp_out_len;
    }
    
@@ -667,6 +672,12 @@ void speex_resampler_set_rate(SpeexResamplerState *st, int in_rate, int out_rate
    speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
 }
 
+void speex_resampler_get_rate(SpeexResamplerState *st, int *in_rate, int *out_rate)
+{
+   *in_rate = st->in_rate;
+   *out_rate = st->out_rate;
+}
+
 void speex_resampler_set_rate_frac(SpeexResamplerState *st, int ratio_num, int ratio_den, int in_rate, int out_rate)
 {
    int fact;
@@ -691,6 +702,12 @@ void speex_resampler_set_rate_frac(SpeexResamplerState *st, int ratio_num, int r
       update_filter(st);
 }
 
+void speex_resampler_get_ratio(SpeexResamplerState *st, int *ratio_num, int *ratio_den)
+{
+   *ratio_num = st->num_rate;
+   *ratio_den = st->den_rate;
+}
+
 void speex_resampler_set_quality(SpeexResamplerState *st, int quality)
 {
    if (quality < 0)
@@ -704,16 +721,31 @@ void speex_resampler_set_quality(SpeexResamplerState *st, int quality)
       update_filter(st);
 }
 
+void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
+{
+   *quality = st->quality;
+}
+
 void speex_resampler_set_input_stride(SpeexResamplerState *st, int stride)
 {
    st->in_stride = stride;
 }
 
+void speex_resampler_get_input_stride(SpeexResamplerState *st, int *stride)
+{
+   *stride = st->in_stride;
+}
+
 void speex_resampler_set_output_stride(SpeexResamplerState *st, int stride)
 {
    st->out_stride = stride;
 }
 
+void speex_resampler_get_output_stride(SpeexResamplerState *st, int *stride)
+{
+   *stride = st->out_stride;
+}
+
 void speex_resampler_skip_zeros(SpeexResamplerState *st)
 {
    int i;