gst_plugins_base/gst/audioresample/resample.c
branchRCL_3
changeset 30 7e817e7e631c
parent 0 0e761a78d257
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
       
     1 /* Resampling library
       
     2  * Copyright (C) <2001> David A. Schleef <ds@schleef.org>
       
     3  *
       
     4  * This library is free software; you can redistribute it and/or
       
     5  * modify it under the terms of the GNU Library General Public
       
     6  * License as published by the Free Software Foundation; either
       
     7  * version 2 of the License, or any later version.
       
     8  *
       
     9  * This library is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12  * Library General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU Library General Public
       
    15  * License along with this library; if not, write to the
       
    16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    17  * Boston, MA 02111-1307, USA.
       
    18  */
       
    19 
       
    20 #ifdef HAVE_CONFIG_H
       
    21 #ifndef __SYMBIAN32__
       
    22 #include <config.h>
       
    23 #else
       
    24 #include "config.h"
       
    25 #endif
       
    26 #endif
       
    27 
       
    28 
       
    29 #include <string.h>
       
    30 #include <math.h>
       
    31 #include <stdio.h>
       
    32 #include <stdlib.h>
       
    33 #include <limits.h>
       
    34 #ifndef __SYMBIAN32__
       
    35 #include <liboil/liboil.h>
       
    36 #endif
       
    37 
       
    38 #include "resample.h"
       
    39 #include "buffer.h"
       
    40 #include "debug.h"
       
    41 
       
    42 void resample_scale_ref (ResampleState * r);
       
    43 void resample_scale_functable (ResampleState * r);
       
    44 
       
    45 GST_DEBUG_CATEGORY (libaudioresample_debug);
       
    46 
       
    47 #ifdef __SYMBIAN32__
       
    48 EXPORT_C
       
    49 #endif
       
    50 void
       
    51 resample_init (void)
       
    52 {
       
    53   static int inited = 0;
       
    54 #ifndef __SYMBIAN32__
       
    55   if (!inited) {
       
    56     oil_init ();
       
    57     inited = 1;
       
    58     GST_DEBUG_CATEGORY_INIT (libaudioresample_debug, "libaudioresample", 0,
       
    59         "audio resampling library");
       
    60 
       
    61   }
       
    62 #endif  
       
    63 }
       
    64 #ifdef __SYMBIAN32__
       
    65 EXPORT_C
       
    66 #endif
       
    67 
       
    68 
       
    69 ResampleState *
       
    70 resample_new (void)
       
    71 {
       
    72   ResampleState *r;
       
    73 
       
    74   r = malloc (sizeof (ResampleState));
       
    75   memset (r, 0, sizeof (ResampleState));
       
    76 
       
    77   r->filter_length = 16;
       
    78 
       
    79   r->i_start = 0;
       
    80   if (r->filter_length & 1) {
       
    81     r->o_start = 0;
       
    82   } else {
       
    83     r->o_start = r->o_inc * 0.5;
       
    84   }
       
    85 
       
    86   r->queue = audioresample_buffer_queue_new ();
       
    87   r->out_tmp = malloc (10000 * sizeof (double));
       
    88 
       
    89   r->need_reinit = 1;
       
    90 
       
    91   return r;
       
    92 }
       
    93 #ifdef __SYMBIAN32__
       
    94 EXPORT_C
       
    95 #endif
       
    96 
       
    97 
       
    98 void
       
    99 resample_free (ResampleState * r)
       
   100 {
       
   101   if (r->buffer) {
       
   102     free (r->buffer);
       
   103   }
       
   104   if (r->ft) {
       
   105     functable_free (r->ft);
       
   106   }
       
   107   if (r->queue) {
       
   108     audioresample_buffer_queue_free (r->queue);
       
   109   }
       
   110   if (r->out_tmp) {
       
   111     free (r->out_tmp);
       
   112   }
       
   113 
       
   114   free (r);
       
   115 }
       
   116 
       
   117 static void
       
   118 resample_buffer_free (AudioresampleBuffer * buffer, void *priv)
       
   119 {
       
   120   if (buffer->priv2) {
       
   121     ((void (*)(void *)) buffer->priv2) (buffer->priv);
       
   122   }
       
   123 }
       
   124 
       
   125 /*
       
   126  * free_func: a function that frees the given closure.  If NULL, caller is
       
   127  *            responsible for freeing.
       
   128  */
       
   129 #ifdef __SYMBIAN32__
       
   130 EXPORT_C
       
   131 #endif
       
   132 
       
   133 void
       
   134 resample_add_input_data (ResampleState * r, void *data, int size,
       
   135     void (*free_func) (void *), void *closure)
       
   136 {
       
   137   AudioresampleBuffer *buffer;
       
   138 
       
   139   RESAMPLE_DEBUG ("data %p size %d", data, size);
       
   140 
       
   141   buffer = audioresample_buffer_new_with_data (data, size);
       
   142   buffer->free = resample_buffer_free;
       
   143   buffer->priv2 = (void *) free_func;
       
   144   buffer->priv = closure;
       
   145 
       
   146   audioresample_buffer_queue_push (r->queue, buffer);
       
   147 }
       
   148 #ifdef __SYMBIAN32__
       
   149 EXPORT_C
       
   150 #endif
       
   151 
       
   152 
       
   153 void
       
   154 resample_input_flush (ResampleState * r)
       
   155 {
       
   156   RESAMPLE_DEBUG ("flush");
       
   157 
       
   158   audioresample_buffer_queue_flush (r->queue);
       
   159   r->buffer_filled = 0;
       
   160   r->need_reinit = 1;
       
   161 }
       
   162 #ifdef __SYMBIAN32__
       
   163 EXPORT_C
       
   164 #endif
       
   165 
       
   166 
       
   167 void
       
   168 resample_input_pushthrough (ResampleState * r)
       
   169 {
       
   170   AudioresampleBuffer *buffer;
       
   171   int filter_bytes;
       
   172   int buffer_filled;
       
   173 
       
   174   if (r->sample_size == 0)
       
   175     return;
       
   176 
       
   177   filter_bytes = r->filter_length * r->sample_size;
       
   178   buffer_filled = r->buffer_filled;
       
   179 
       
   180   RESAMPLE_DEBUG ("pushthrough filter_bytes %d, filled %d",
       
   181       filter_bytes, buffer_filled);
       
   182 
       
   183   /* if we have no pending samples, we don't need to do anything. */
       
   184   if (buffer_filled <= 0)
       
   185     return;
       
   186 
       
   187   /* send filter_length/2 number of samples so we can get to the
       
   188    * last queued samples */
       
   189   buffer = audioresample_buffer_new_and_alloc (filter_bytes / 2);
       
   190   memset (buffer->data, 0, buffer->length);
       
   191 
       
   192   RESAMPLE_DEBUG ("pushthrough %u", buffer->length);
       
   193 
       
   194   audioresample_buffer_queue_push (r->queue, buffer);
       
   195 }
       
   196 #ifdef __SYMBIAN32__
       
   197 EXPORT_C
       
   198 #endif
       
   199 
       
   200 
       
   201 void
       
   202 resample_input_eos (ResampleState * r)
       
   203 {
       
   204   RESAMPLE_DEBUG ("EOS");
       
   205   resample_input_pushthrough (r);
       
   206   r->eos = 1;
       
   207 }
       
   208 #ifdef __SYMBIAN32__
       
   209 EXPORT_C
       
   210 #endif
       
   211 
       
   212 
       
   213 int
       
   214 resample_get_output_size_for_input (ResampleState * r, int size)
       
   215 {
       
   216   int outsize;
       
   217   double outd;
       
   218   int avail;
       
   219   int filter_bytes;
       
   220   int buffer_filled;
       
   221 
       
   222   if (r->sample_size == 0)
       
   223     return 0;
       
   224 
       
   225   filter_bytes = r->filter_length * r->sample_size;
       
   226   buffer_filled = filter_bytes / 2 - r->buffer_filled / 2;
       
   227 
       
   228   avail =
       
   229       audioresample_buffer_queue_get_depth (r->queue) + size - buffer_filled;
       
   230 
       
   231   RESAMPLE_DEBUG ("avail %d, o_rate %f, i_rate %f, filter_bytes %d, filled %d",
       
   232       avail, r->o_rate, r->i_rate, filter_bytes, buffer_filled);
       
   233   if (avail <= 0)
       
   234     return 0;
       
   235 
       
   236   outd = (double) avail *r->o_rate / r->i_rate;
       
   237 
       
   238   outsize = (int) floor (outd);
       
   239 
       
   240   /* round off for sample size */
       
   241   outsize -= outsize % r->sample_size;
       
   242 
       
   243   return outsize;
       
   244 }
       
   245 #ifdef __SYMBIAN32__
       
   246 EXPORT_C
       
   247 #endif
       
   248 
       
   249 
       
   250 int
       
   251 resample_get_input_size_for_output (ResampleState * r, int size)
       
   252 {
       
   253   int outsize;
       
   254   double outd;
       
   255   int avail;
       
   256 
       
   257   if (r->sample_size == 0)
       
   258     return 0;
       
   259 
       
   260   avail = size;
       
   261 
       
   262   RESAMPLE_DEBUG ("size %d, o_rate %f, i_rate %f", avail, r->o_rate, r->i_rate);
       
   263   outd = (double) avail *r->i_rate / r->o_rate;
       
   264 
       
   265   outsize = (int) ceil (outd);
       
   266 
       
   267   /* round off for sample size */
       
   268   outsize -= outsize % r->sample_size;
       
   269 
       
   270   return outsize;
       
   271 }
       
   272 #ifdef __SYMBIAN32__
       
   273 EXPORT_C
       
   274 #endif
       
   275 
       
   276 
       
   277 int
       
   278 resample_get_output_size (ResampleState * r)
       
   279 {
       
   280   return resample_get_output_size_for_input (r, 0);
       
   281 }
       
   282 #ifdef __SYMBIAN32__
       
   283 EXPORT_C
       
   284 #endif
       
   285 
       
   286 
       
   287 int
       
   288 resample_get_output_data (ResampleState * r, void *data, int size)
       
   289 {
       
   290   r->o_buf = data;
       
   291   r->o_size = size;
       
   292 
       
   293   if (size == 0)
       
   294     return 0;
       
   295 
       
   296   switch (r->method) {
       
   297     case 0:
       
   298       resample_scale_ref (r);
       
   299       break;
       
   300     case 1:
       
   301       resample_scale_functable (r);
       
   302       break;
       
   303     default:
       
   304       break;
       
   305   }
       
   306 
       
   307   return size - r->o_size;
       
   308 }
       
   309 #ifdef __SYMBIAN32__
       
   310 EXPORT_C
       
   311 #endif
       
   312 
       
   313 
       
   314 void
       
   315 resample_set_filter_length (ResampleState * r, int length)
       
   316 {
       
   317   r->filter_length = length;
       
   318   r->need_reinit = 1;
       
   319 }
       
   320 #ifdef __SYMBIAN32__
       
   321 EXPORT_C
       
   322 #endif
       
   323 
       
   324 
       
   325 void
       
   326 resample_set_input_rate (ResampleState * r, double rate)
       
   327 {
       
   328   r->i_rate = rate;
       
   329   r->need_reinit = 1;
       
   330 }
       
   331 #ifdef __SYMBIAN32__
       
   332 EXPORT_C
       
   333 #endif
       
   334 
       
   335 
       
   336 void
       
   337 resample_set_output_rate (ResampleState * r, double rate)
       
   338 {
       
   339   r->o_rate = rate;
       
   340   r->need_reinit = 1;
       
   341 }
       
   342 #ifdef __SYMBIAN32__
       
   343 EXPORT_C
       
   344 #endif
       
   345 
       
   346 
       
   347 void
       
   348 resample_set_n_channels (ResampleState * r, int n_channels)
       
   349 {
       
   350   r->n_channels = n_channels;
       
   351   r->sample_size = r->n_channels * resample_format_size (r->format);
       
   352   r->need_reinit = 1;
       
   353 }
       
   354 #ifdef __SYMBIAN32__
       
   355 EXPORT_C
       
   356 #endif
       
   357 
       
   358 
       
   359 void
       
   360 resample_set_format (ResampleState * r, ResampleFormat format)
       
   361 {
       
   362   r->format = format;
       
   363   r->sample_size = r->n_channels * resample_format_size (r->format);
       
   364   r->need_reinit = 1;
       
   365 }
       
   366 #ifdef __SYMBIAN32__
       
   367 EXPORT_C
       
   368 #endif
       
   369 
       
   370 
       
   371 void
       
   372 resample_set_method (ResampleState * r, int method)
       
   373 {
       
   374   r->method = method;
       
   375   r->need_reinit = 1;
       
   376 }
       
   377 #ifdef __SYMBIAN32__
       
   378 EXPORT_C
       
   379 #endif
       
   380 
       
   381 
       
   382 int
       
   383 resample_format_size (ResampleFormat format)
       
   384 {
       
   385   switch (format) {
       
   386     case RESAMPLE_FORMAT_S16:
       
   387       return 2;
       
   388     case RESAMPLE_FORMAT_S32:
       
   389     case RESAMPLE_FORMAT_F32:
       
   390       return 4;
       
   391     case RESAMPLE_FORMAT_F64:
       
   392       return 8;
       
   393   }
       
   394   return 0;
       
   395 }