ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

src_linear.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 /*
00020 ** This code is part of Secret Rabbit Code aka libsamplerate. A commercial
00021 ** use license for this code is available, please see:
00022 **      http://www.mega-nerd.com/SRC/procedure.html
00023 */
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 #include "config.h"
00030 #include "float_cast.h"
00031 #include "common.h"
00032 
00033 static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
00034 static void linear_reset (SRC_PRIVATE *psrc) ;
00035 
00036 /*========================================================================================
00037 */
00038 
00039 #define LINEAR_MAGIC_MARKER MAKE_MAGIC ('l', 'i', 'n', 'e', 'a', 'r')
00040 
00041 #define SRC_DEBUG   0
00042 
00043 typedef struct
00044 {   int     linear_magic_marker ;
00045     int     channels ;
00046     int     reset ;
00047     long    in_count, in_used ;
00048     long    out_count, out_gen ;
00049     float   last_value [1] ;
00050 } LINEAR_DATA ;
00051 
00052 /*----------------------------------------------------------------------------------------
00053 */
00054 
00055 static int
00056 linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
00057 {   LINEAR_DATA *priv ;
00058     double      src_ratio, input_index, rem ;
00059     int         ch ;
00060 
00061     if (data->input_frames <= 0)
00062         return SRC_ERR_NO_ERROR ;
00063 
00064     if (psrc->private_data == NULL)
00065         return SRC_ERR_NO_PRIVATE ;
00066 
00067     priv = (LINEAR_DATA*) psrc->private_data ;
00068 
00069     if (priv->reset)
00070     {   /* If we have just been reset, set the last_value data. */
00071         for (ch = 0 ; ch < priv->channels ; ch++)
00072             priv->last_value [ch] = data->data_in [ch] ;
00073         priv->reset = 0 ;
00074         } ;
00075 
00076     priv->in_count = data->input_frames * priv->channels ;
00077     priv->out_count = data->output_frames * priv->channels ;
00078     priv->in_used = priv->out_gen = 0 ;
00079 
00080     src_ratio = psrc->last_ratio ;
00081     input_index = psrc->last_position ;
00082 
00083     /* Calculate samples before first sample in input array. */
00084     while (input_index < 1.0 && priv->out_gen < priv->out_count)
00085     {
00086         if (priv->in_used + priv->channels * (1.0 + input_index) >= priv->in_count)
00087             break ;
00088 
00089         if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
00090             src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
00091 
00092         for (ch = 0 ; ch < priv->channels ; ch++)
00093         {   data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index *
00094                                         (data->data_in [ch] - priv->last_value [ch])) ;
00095             priv->out_gen ++ ;
00096             } ;
00097 
00098         /* Figure out the next index. */
00099         input_index += 1.0 / src_ratio ;
00100         } ;
00101 
00102     rem = fmod_one (input_index) ;
00103     priv->in_used += priv->channels * lrint (input_index - rem) ;
00104     input_index = rem ;
00105 
00106     /* Main processing loop. */
00107     while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index < priv->in_count)
00108     {
00109         if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
00110             src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
00111 
00112         if (SRC_DEBUG && priv->in_used < priv->channels && input_index < 1.0)
00113         {   printf ("Whoops!!!!   in_used : %ld     channels : %d     input_index : %f\n", priv->in_used, priv->channels, input_index) ;
00114             exit (1) ;
00115             } ;
00116 
00117         for (ch = 0 ; ch < priv->channels ; ch++)
00118         {   data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - priv->channels + ch] + input_index *
00119                         (data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - priv->channels + ch])) ;
00120             priv->out_gen ++ ;
00121             } ;
00122 
00123         /* Figure out the next index. */
00124         input_index += 1.0 / src_ratio ;
00125         rem = fmod_one (input_index) ;
00126 
00127         priv->in_used += priv->channels * lrint (input_index - rem) ;
00128         input_index = rem ;
00129         } ;
00130 
00131     if (priv->in_used > priv->in_count)
00132     {   input_index += (priv->in_used - priv->in_count) / priv->channels ;
00133         priv->in_used = priv->in_count ;
00134         } ;
00135 
00136     psrc->last_position = input_index ;
00137 
00138     if (priv->in_used > 0)
00139         for (ch = 0 ; ch < priv->channels ; ch++)
00140             priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ;
00141 
00142     /* Save current ratio rather then target ratio. */
00143     psrc->last_ratio = src_ratio ;
00144 
00145     data->input_frames_used = priv->in_used / priv->channels ;
00146     data->output_frames_gen = priv->out_gen / priv->channels ;
00147 
00148     return SRC_ERR_NO_ERROR ;
00149 } /* linear_vari_process */
00150 
00151 /*------------------------------------------------------------------------------
00152 */
00153 
00154 const char*
00155 linear_get_name (int src_enum)
00156 {
00157     if (src_enum == SRC_LINEAR)
00158         return "Linear Interpolator" ;
00159 
00160     return NULL ;
00161 } /* linear_get_name */
00162 
00163 const char*
00164 linear_get_description (int src_enum)
00165 {
00166     if (src_enum == SRC_LINEAR)
00167         return "Linear interpolator, very fast, poor quality." ;
00168 
00169     return NULL ;
00170 } /* linear_get_descrition */
00171 
00172 int
00173 linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
00174 {   LINEAR_DATA *priv = NULL ;
00175 
00176     if (src_enum != SRC_LINEAR)
00177         return SRC_ERR_BAD_CONVERTER ;
00178 
00179     if (psrc->private_data != NULL)
00180     {   free (psrc->private_data) ;
00181         psrc->private_data = NULL ;
00182         } ;
00183 
00184     if (psrc->private_data == NULL)
00185     {   priv = calloc (1, sizeof (*priv) + psrc->channels * sizeof (float)) ;
00186         if (priv == NULL)
00187             return SRC_ERR_MALLOC_FAILED ;
00188         psrc->private_data = priv ;
00189         } ;
00190 
00191     priv->linear_magic_marker = LINEAR_MAGIC_MARKER ;
00192     priv->channels = psrc->channels ;
00193 
00194     psrc->const_process = linear_vari_process ;
00195     psrc->vari_process = linear_vari_process ;
00196     psrc->reset = linear_reset ;
00197 
00198     linear_reset (psrc) ;
00199 
00200     return SRC_ERR_NO_ERROR ;
00201 } /* linear_set_converter */
00202 
00203 /*===================================================================================
00204 */
00205 
00206 static void
00207 linear_reset (SRC_PRIVATE *psrc)
00208 {   LINEAR_DATA *priv = NULL ;
00209 
00210     priv = (LINEAR_DATA*) psrc->private_data ;
00211     if (priv == NULL)
00212         return ;
00213 
00214     priv->channels = psrc->channels ;
00215     priv->reset = 1 ;
00216     memset (priv->last_value, 0, sizeof (priv->last_value [0]) * priv->channels) ;
00217 
00218     return ;
00219 } /* linear_reset */
00220 

Generated on Sat May 26 2012 04:33:05 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.