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_zoh.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 zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
00034 static void zoh_reset (SRC_PRIVATE *psrc) ;
00035 
00036 /*========================================================================================
00037 */
00038 
00039 #define ZOH_MAGIC_MARKER    MAKE_MAGIC ('s', 'r', 'c', 'z', 'o', 'h')
00040 
00041 typedef struct
00042 {   int     zoh_magic_marker ;
00043     int     channels ;
00044     int     reset ;
00045     long    in_count, in_used ;
00046     long    out_count, out_gen ;
00047     float   last_value [1] ;
00048 } ZOH_DATA ;
00049 
00050 /*----------------------------------------------------------------------------------------
00051 */
00052 
00053 static int
00054 zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
00055 {   ZOH_DATA    *priv ;
00056     double      src_ratio, input_index, rem ;
00057     int         ch ;
00058 
00059     if (data->input_frames <= 0)
00060         return SRC_ERR_NO_ERROR ;
00061 
00062     if (psrc->private_data == NULL)
00063         return SRC_ERR_NO_PRIVATE ;
00064 
00065     priv = (ZOH_DATA*) psrc->private_data ;
00066 
00067     if (priv->reset)
00068     {   /* If we have just been reset, set the last_value data. */
00069         for (ch = 0 ; ch < priv->channels ; ch++)
00070             priv->last_value [ch] = data->data_in [ch] ;
00071         priv->reset = 0 ;
00072         } ;
00073 
00074     priv->in_count = data->input_frames * priv->channels ;
00075     priv->out_count = data->output_frames * priv->channels ;
00076     priv->in_used = priv->out_gen = 0 ;
00077 
00078     src_ratio = psrc->last_ratio ;
00079     input_index = psrc->last_position ;
00080 
00081     /* Calculate samples before first sample in input array. */
00082     while (input_index < 1.0 && priv->out_gen < priv->out_count)
00083     {
00084         if (priv->in_used + priv->channels * input_index >= priv->in_count)
00085             break ;
00086 
00087         if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
00088             src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
00089 
00090         for (ch = 0 ; ch < priv->channels ; ch++)
00091         {   data->data_out [priv->out_gen] = priv->last_value [ch] ;
00092             priv->out_gen ++ ;
00093             } ;
00094 
00095         /* Figure out the next index. */
00096         input_index += 1.0 / src_ratio ;
00097         } ;
00098 
00099     rem = fmod_one (input_index) ;
00100     priv->in_used += priv->channels * lrint (input_index - rem) ;
00101     input_index = rem ;
00102 
00103     /* Main processing loop. */
00104     while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index <= priv->in_count)
00105     {
00106         if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
00107             src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
00108 
00109         for (ch = 0 ; ch < priv->channels ; ch++)
00110         {   data->data_out [priv->out_gen] = data->data_in [priv->in_used - priv->channels + ch] ;
00111             priv->out_gen ++ ;
00112             } ;
00113 
00114         /* Figure out the next index. */
00115         input_index += 1.0 / src_ratio ;
00116         rem = fmod_one (input_index) ;
00117 
00118         priv->in_used += priv->channels * lrint (input_index - rem) ;
00119         input_index = rem ;
00120         } ;
00121 
00122     if (priv->in_used > priv->in_count)
00123     {   input_index += (priv->in_used - priv->in_count) / priv->channels ;
00124         priv->in_used = priv->in_count ;
00125         } ;
00126 
00127     psrc->last_position = input_index ;
00128 
00129     if (priv->in_used > 0)
00130         for (ch = 0 ; ch < priv->channels ; ch++)
00131             priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ;
00132 
00133     /* Save current ratio rather then target ratio. */
00134     psrc->last_ratio = src_ratio ;
00135 
00136     data->input_frames_used = priv->in_used / priv->channels ;
00137     data->output_frames_gen = priv->out_gen / priv->channels ;
00138 
00139     return SRC_ERR_NO_ERROR ;
00140 } /* zoh_vari_process */
00141 
00142 /*------------------------------------------------------------------------------
00143 */
00144 
00145 const char*
00146 zoh_get_name (int src_enum)
00147 {
00148     if (src_enum == SRC_ZERO_ORDER_HOLD)
00149         return "ZOH Interpolator" ;
00150 
00151     return NULL ;
00152 } /* zoh_get_name */
00153 
00154 const char*
00155 zoh_get_description (int src_enum)
00156 {
00157     if (src_enum == SRC_ZERO_ORDER_HOLD)
00158         return "Zero order hold interpolator, very fast, poor quality." ;
00159 
00160     return NULL ;
00161 } /* zoh_get_descrition */
00162 
00163 int
00164 zoh_set_converter (SRC_PRIVATE *psrc, int src_enum)
00165 {   ZOH_DATA *priv = NULL ;
00166 
00167     if (src_enum != SRC_ZERO_ORDER_HOLD)
00168         return SRC_ERR_BAD_CONVERTER ;
00169 
00170     if (psrc->private_data != NULL)
00171     {   free (psrc->private_data) ;
00172         psrc->private_data = NULL ;
00173         } ;
00174 
00175     if (psrc->private_data == NULL)
00176     {   priv = calloc (1, sizeof (*priv) + psrc->channels * sizeof (float)) ;
00177         if (priv == NULL)
00178             return SRC_ERR_MALLOC_FAILED ;
00179         psrc->private_data = priv ;
00180         } ;
00181 
00182     priv->zoh_magic_marker = ZOH_MAGIC_MARKER ;
00183     priv->channels = psrc->channels ;
00184 
00185     psrc->const_process = zoh_vari_process ;
00186     psrc->vari_process = zoh_vari_process ;
00187     psrc->reset = zoh_reset ;
00188 
00189     zoh_reset (psrc) ;
00190 
00191     return SRC_ERR_NO_ERROR ;
00192 } /* zoh_set_converter */
00193 
00194 /*===================================================================================
00195 */
00196 
00197 static void
00198 zoh_reset (SRC_PRIVATE *psrc)
00199 {   ZOH_DATA *priv ;
00200 
00201     priv = (ZOH_DATA*) psrc->private_data ;
00202     if (priv == NULL)
00203         return ;
00204 
00205     priv->channels = psrc->channels ;
00206     priv->reset = 1 ;
00207     memset (priv->last_value, 0, sizeof (priv->last_value [0]) * priv->channels) ;
00208 
00209     return ;
00210 } /* zoh_reset */
00211 

Generated on Sun May 27 2012 04:34:13 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.