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

samplerate.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 
00031 #include    "samplerate.h"
00032 #include    "float_cast.h"
00033 #include    "common.h"
00034 
00035 static int psrc_set_converter (SRC_PRIVATE  *psrc, int converter_type) ;
00036 
00037 
00038 static inline int
00039 is_bad_src_ratio (double ratio)
00040 {   return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
00041 } /* is_bad_src_ratio */
00042 
00043 SRC_STATE *
00044 src_new (int converter_type, int channels, int *error)
00045 {   SRC_PRIVATE *psrc ;
00046 
00047     if (error)
00048         *error = SRC_ERR_NO_ERROR ;
00049 
00050     if (channels < 1)
00051     {   if (error)
00052             *error = SRC_ERR_BAD_CHANNEL_COUNT ;
00053         return NULL ;
00054         } ;
00055 
00056     if ((psrc = calloc (1, sizeof (*psrc))) == NULL)
00057     {   if (error)
00058             *error = SRC_ERR_MALLOC_FAILED ;
00059         return NULL ;
00060         } ;
00061 
00062     psrc->channels = channels ;
00063     psrc->mode = SRC_MODE_PROCESS ;
00064 
00065     if (psrc_set_converter (psrc, converter_type) != SRC_ERR_NO_ERROR)
00066     {   if (error)
00067             *error = SRC_ERR_BAD_CONVERTER ;
00068         free (psrc) ;
00069         psrc = NULL ;
00070         } ;
00071 
00072     src_reset ((SRC_STATE*) psrc) ;
00073 
00074     return (SRC_STATE*) psrc ;
00075 } /* src_new */
00076 
00077 SRC_STATE*
00078 src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data)
00079 {   SRC_STATE   *src_state ;
00080 
00081     if (func == NULL)
00082     {   if (error)
00083             *error = SRC_ERR_BAD_CALLBACK ;
00084         return NULL ;
00085         } ;
00086 
00087     if (error != NULL)
00088         *error = 0 ;
00089 
00090     if ((src_state = src_new (converter_type, channels, error)) == NULL)
00091         return NULL ;
00092 
00093     src_reset (src_state) ;
00094 
00095     ((SRC_PRIVATE*) src_state)->mode = SRC_MODE_CALLBACK ;
00096     ((SRC_PRIVATE*) src_state)->callback_func = func ;
00097     ((SRC_PRIVATE*) src_state)->user_callback_data = cb_data ;
00098 
00099     return src_state ;
00100 } /* src_callback_new */
00101 
00102 SRC_STATE *
00103 src_delete (SRC_STATE *state)
00104 {   SRC_PRIVATE *psrc ;
00105 
00106     psrc = (SRC_PRIVATE*) state ;
00107     if (psrc)
00108     {   if (psrc->private_data)
00109             free (psrc->private_data) ;
00110         memset (psrc, 0, sizeof (SRC_PRIVATE)) ;
00111         free (psrc) ;
00112         } ;
00113 
00114     return NULL ;
00115 } /* src_state */
00116 
00117 int
00118 src_process (SRC_STATE *state, SRC_DATA *data)
00119 {   SRC_PRIVATE *psrc ;
00120     int error ;
00121 
00122     psrc = (SRC_PRIVATE*) state ;
00123 
00124     if (psrc == NULL)
00125         return SRC_ERR_BAD_STATE ;
00126     if (psrc->vari_process == NULL || psrc->const_process == NULL)
00127         return SRC_ERR_BAD_PROC_PTR ;
00128 
00129     if (psrc->mode != SRC_MODE_PROCESS)
00130         return SRC_ERR_BAD_MODE ;
00131 
00132     /* Check for valid SRC_DATA first. */
00133     if (data == NULL)
00134         return SRC_ERR_BAD_DATA ;
00135 
00136     /* And that data_in and data_out are valid. */
00137     if (data->data_in == NULL || data->data_out == NULL)
00138         return SRC_ERR_BAD_DATA_PTR ;
00139 
00140     /* Check src_ratio is in range. */
00141     if (is_bad_src_ratio (data->src_ratio))
00142         return SRC_ERR_BAD_SRC_RATIO ;
00143 
00144     if (data->input_frames < 0)
00145         data->input_frames = 0 ;
00146     if (data->output_frames < 0)
00147         data->output_frames = 0 ;
00148 
00149     if (data->data_in < data->data_out)
00150     {   if (data->data_in + data->input_frames * psrc->channels > data->data_out)
00151         {   /*-printf ("\n\ndata_in: %p    data_out: %p\n",
00152                 (void*) (data->data_in + data->input_frames * psrc->channels), (void*) data->data_out) ;-*/
00153             return SRC_ERR_DATA_OVERLAP ;
00154             } ;
00155         }
00156     else if (data->data_out + data->output_frames * psrc->channels > data->data_in)
00157     {   /*-printf ("\n\ndata_in : %p   ouput frames: %ld    data_out: %p\n", (void*) data->data_in, data->output_frames, (void*) data->data_out) ;
00158 
00159         printf ("data_out: %p (%p)    data_in: %p\n", (void*) data->data_out,
00160             (void*) (data->data_out + data->input_frames * psrc->channels), (void*) data->data_in) ;-*/
00161         return SRC_ERR_DATA_OVERLAP ;
00162         } ;
00163 
00164     /* Set the input and output counts to zero. */
00165     data->input_frames_used = 0 ;
00166     data->output_frames_gen = 0 ;
00167 
00168     /* Special case for when last_ratio has not been set. */
00169     if (psrc->last_ratio < (1.0 / SRC_MAX_RATIO))
00170         psrc->last_ratio = data->src_ratio ;
00171 
00172     /* Now process. */
00173     if (fabs (psrc->last_ratio - data->src_ratio) < 1e-15)
00174         error = psrc->const_process (psrc, data) ;
00175     else
00176         error = psrc->vari_process (psrc, data) ;
00177 
00178     return error ;
00179 } /* src_process */
00180 
00181 long
00182 src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
00183 {   SRC_PRIVATE *psrc ;
00184     SRC_DATA    src_data ;
00185 
00186     long    output_frames_gen ;
00187     int     error = 0 ;
00188 
00189     if (state == NULL)
00190         return 0 ;
00191 
00192     if (frames <= 0)
00193         return 0 ;
00194 
00195     psrc = (SRC_PRIVATE*) state ;
00196 
00197     if (psrc->mode != SRC_MODE_CALLBACK)
00198     {   psrc->error = SRC_ERR_BAD_MODE ;
00199         return 0 ;
00200         } ;
00201 
00202     if (psrc->callback_func == NULL)
00203     {   psrc->error = SRC_ERR_NULL_CALLBACK ;
00204         return 0 ;
00205         } ;
00206 
00207     memset (&src_data, 0, sizeof (src_data)) ;
00208 
00209     /* Check src_ratio is in range. */
00210     if (is_bad_src_ratio (src_ratio))
00211     {   psrc->error = SRC_ERR_BAD_SRC_RATIO ;
00212         return 0 ;
00213         } ;
00214 
00215     /* Switch modes temporarily. */
00216     src_data.src_ratio = src_ratio ;
00217     src_data.data_out = data ;
00218     src_data.output_frames = frames ;
00219 
00220     src_data.data_in = psrc->saved_data ;
00221     src_data.input_frames = psrc->saved_frames ;
00222 
00223     output_frames_gen = 0 ;
00224     while (output_frames_gen < frames)
00225     {   /*  Use a dummy array for the case where the callback function
00226         **  returns without setting the ptr.
00227         */
00228         float dummy [1] ;
00229 
00230         if (src_data.input_frames == 0)
00231         {   float *ptr = dummy ;
00232 
00233             src_data.input_frames = psrc->callback_func (psrc->user_callback_data, &ptr) ;
00234             src_data.data_in = ptr ;
00235 
00236             if (src_data.input_frames == 0)
00237                 src_data.end_of_input = 1 ;
00238             } ;
00239 
00240         /*
00241         ** Now call process function. However, we need to set the mode
00242         ** to SRC_MODE_PROCESS first and when we return set it back to
00243         ** SRC_MODE_CALLBACK.
00244         */
00245         psrc->mode = SRC_MODE_PROCESS ;
00246         error = src_process (state, &src_data) ;
00247         psrc->mode = SRC_MODE_CALLBACK ;
00248 
00249         if (error != 0)
00250             break ;
00251 
00252         src_data.data_in += src_data.input_frames_used * psrc->channels ;
00253         src_data.input_frames -= src_data.input_frames_used ;
00254 
00255         src_data.data_out += src_data.output_frames_gen * psrc->channels ;
00256         src_data.output_frames -= src_data.output_frames_gen ;
00257 
00258         output_frames_gen += src_data.output_frames_gen ;
00259 
00260         if (src_data.end_of_input == SRC_TRUE && src_data.output_frames_gen == 0)
00261             break ;
00262         } ;
00263 
00264     psrc->saved_data = src_data.data_in ;
00265     psrc->saved_frames = src_data.input_frames ;
00266 
00267     if (error != 0)
00268     {   psrc->error = error ;
00269         return 0 ;
00270         } ;
00271 
00272     return output_frames_gen ;
00273 } /* src_callback_read */
00274 
00275 /*==========================================================================
00276 */
00277 
00278 int
00279 src_set_ratio (SRC_STATE *state, double new_ratio)
00280 {   SRC_PRIVATE *psrc ;
00281 
00282     psrc = (SRC_PRIVATE*) state ;
00283 
00284     if (psrc == NULL)
00285         return SRC_ERR_BAD_STATE ;
00286     if (psrc->vari_process == NULL || psrc->const_process == NULL)
00287         return SRC_ERR_BAD_PROC_PTR ;
00288 
00289     if (is_bad_src_ratio (new_ratio))
00290         return SRC_ERR_BAD_SRC_RATIO ;
00291 
00292     psrc->last_ratio = new_ratio ;
00293 
00294     return SRC_ERR_NO_ERROR ;
00295 } /* src_set_ratio */
00296 
00297 int
00298 src_reset (SRC_STATE *state)
00299 {   SRC_PRIVATE *psrc ;
00300 
00301     if ((psrc = (SRC_PRIVATE*) state) == NULL)
00302         return SRC_ERR_BAD_STATE ;
00303 
00304     if (psrc->reset != NULL)
00305         psrc->reset (psrc) ;
00306 
00307     psrc->last_position = 0.0 ;
00308     psrc->last_ratio = 0.0 ;
00309 
00310     psrc->saved_data = NULL ;
00311     psrc->saved_frames = 0 ;
00312 
00313     psrc->error = SRC_ERR_NO_ERROR ;
00314 
00315     return SRC_ERR_NO_ERROR ;
00316 } /* src_reset */
00317 
00318 /*==============================================================================
00319 **  Control functions.
00320 */
00321 
00322 const char *
00323 src_get_name (int converter_type)
00324 {   const char *desc ;
00325 
00326     if ((desc = sinc_get_name (converter_type)) != NULL)
00327         return desc ;
00328 
00329     if ((desc = zoh_get_name (converter_type)) != NULL)
00330         return desc ;
00331 
00332     if ((desc = linear_get_name (converter_type)) != NULL)
00333         return desc ;
00334 
00335     return NULL ;
00336 } /* src_get_name */
00337 
00338 const char *
00339 src_get_description (int converter_type)
00340 {   const char *desc ;
00341 
00342     if ((desc = sinc_get_description (converter_type)) != NULL)
00343         return desc ;
00344 
00345     if ((desc = zoh_get_description (converter_type)) != NULL)
00346         return desc ;
00347 
00348     if ((desc = linear_get_description (converter_type)) != NULL)
00349         return desc ;
00350 
00351     return NULL ;
00352 } /* src_get_description */
00353 
00354 const char *
00355 src_get_version (void)
00356 {   return PACKAGE "-" VERSION " (c) 2002-2008 Erik de Castro Lopo" ;
00357 } /* src_get_version */
00358 
00359 int
00360 src_is_valid_ratio (double ratio)
00361 {
00362     if (is_bad_src_ratio (ratio))
00363         return SRC_FALSE ;
00364 
00365     return SRC_TRUE ;
00366 } /* src_is_valid_ratio */
00367 
00368 /*==============================================================================
00369 **  Error reporting functions.
00370 */
00371 
00372 int
00373 src_error (SRC_STATE *state)
00374 {   if (state)
00375         return ((SRC_PRIVATE*) state)->error ;
00376     return SRC_ERR_NO_ERROR ;
00377 } /* src_error */
00378 
00379 const char*
00380 src_strerror (int error)
00381 {
00382     switch (error)
00383     {   case SRC_ERR_NO_ERROR :
00384                 return "No error." ;
00385         case SRC_ERR_MALLOC_FAILED :
00386                 return "Malloc failed." ;
00387         case SRC_ERR_BAD_STATE :
00388                 return "SRC_STATE pointer is NULL." ;
00389         case SRC_ERR_BAD_DATA :
00390                 return "SRC_DATA pointer is NULL." ;
00391         case SRC_ERR_BAD_DATA_PTR :
00392                 return "SRC_DATA->data_out is NULL." ;
00393         case SRC_ERR_NO_PRIVATE :
00394                 return "Internal error. No private data." ;
00395 
00396         case SRC_ERR_BAD_SRC_RATIO :
00397                 return "SRC ratio outside [1/" SRC_MAX_RATIO_STR ", " SRC_MAX_RATIO_STR "] range." ;
00398 
00399         case SRC_ERR_BAD_SINC_STATE :
00400                 return "src_process() called without reset after end_of_input." ;
00401         case SRC_ERR_BAD_PROC_PTR :
00402                 return "Internal error. No process pointer." ;
00403         case SRC_ERR_SHIFT_BITS :
00404                 return "Internal error. SHIFT_BITS too large." ;
00405         case SRC_ERR_FILTER_LEN :
00406                 return "Internal error. Filter length too large." ;
00407         case SRC_ERR_BAD_CONVERTER :
00408                 return "Bad converter number." ;
00409         case SRC_ERR_BAD_CHANNEL_COUNT :
00410                 return "Channel count must be >= 1." ;
00411         case SRC_ERR_SINC_BAD_BUFFER_LEN :
00412                 return "Internal error. Bad buffer length. Please report this." ;
00413         case SRC_ERR_SIZE_INCOMPATIBILITY :
00414                 return "Internal error. Input data / internal buffer size difference. Please report this." ;
00415         case SRC_ERR_BAD_PRIV_PTR :
00416                 return "Internal error. Private pointer is NULL. Please report this." ;
00417         case SRC_ERR_DATA_OVERLAP :
00418                 return "Input and output data arrays overlap." ;
00419         case SRC_ERR_BAD_CALLBACK :
00420                 return "Supplied callback function pointer is NULL." ;
00421         case SRC_ERR_BAD_MODE :
00422                 return "Calling mode differs from initialisation mode (ie process v callback)." ;
00423         case SRC_ERR_NULL_CALLBACK :
00424                 return "Callback function pointer is NULL in src_callback_read ()." ;
00425         case SRC_ERR_NO_VARIABLE_RATIO :
00426                 return "This converter only allows constant conversion ratios." ;
00427         case SRC_ERR_SINC_PREPARE_DATA_BAD_LEN :
00428                 return "Internal error : Bad length in prepare_data ()." ;
00429 
00430         case SRC_ERR_MAX_ERROR :
00431                 return "Placeholder. No error defined for this error number." ;
00432 
00433         default :                       break ;
00434         }
00435 
00436     return NULL ;
00437 } /* src_strerror */
00438 
00439 /*==============================================================================
00440 **  Simple interface for performing a single conversion from input buffer to
00441 **  output buffer at a fixed conversion ratio.
00442 */
00443 
00444 int
00445 src_simple (SRC_DATA *src_data, int converter, int channels)
00446 {   SRC_STATE   *src_state ;
00447     int         error ;
00448 
00449     if ((src_state = src_new (converter, channels, &error)) == NULL)
00450         return error ;
00451 
00452     src_data->end_of_input = 1 ; /* Only one buffer worth of input. */
00453 
00454     error = src_process (src_state, src_data) ;
00455 
00456     src_state = src_delete (src_state) ;
00457 
00458     return error ;
00459 } /* src_simple */
00460 
00461 void
00462 src_short_to_float_array (const short *in, float *out, int len)
00463 {
00464     while (len)
00465     {   len -- ;
00466         out [len] = (float) (in [len] / (1.0 * 0x8000)) ;
00467         } ;
00468 
00469     return ;
00470 } /* src_short_to_float_array */
00471 
00472 void
00473 src_float_to_short_array (const float *in, short *out, int len)
00474 {   double scaled_value ;
00475 
00476     while (len)
00477     {   len -- ;
00478 
00479         scaled_value = in [len] * (8.0 * 0x10000000) ;
00480         if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
00481         {   out [len] = 32767 ;
00482             continue ;
00483             } ;
00484         if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
00485         {   out [len] = -32768 ;
00486             continue ;
00487             } ;
00488 
00489         out [len] = (short) (lrint (scaled_value) >> 16) ;
00490         } ;
00491 
00492 } /* src_float_to_short_array */
00493 
00494 void
00495 src_int_to_float_array (const int *in, float *out, int len)
00496 {
00497     while (len)
00498     {   len -- ;
00499         out [len] = (float) (in [len] / (8.0 * 0x10000000)) ;
00500         } ;
00501 
00502     return ;
00503 } /* src_int_to_float_array */
00504 
00505 void
00506 src_float_to_int_array (const float *in, int *out, int len)
00507 {   double scaled_value ;
00508 
00509     while (len)
00510     {   len -- ;
00511 
00512         scaled_value = in [len] * (8.0 * 0x10000000) ;
00513         if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
00514         {   out [len] = 0x7fffffff ;
00515             continue ;
00516             } ;
00517         if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
00518         {   out [len] = -1 - 0x7fffffff ;
00519             continue ;
00520             } ;
00521 
00522         out [len] = lrint (scaled_value) ;
00523         } ;
00524 
00525 } /* src_float_to_int_array */
00526 
00527 /*==============================================================================
00528 **  Private functions.
00529 */
00530 
00531 static int
00532 psrc_set_converter (SRC_PRIVATE *psrc, int converter_type)
00533 {
00534     if (sinc_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
00535         return SRC_ERR_NO_ERROR ;
00536 
00537     if (zoh_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
00538         return SRC_ERR_NO_ERROR ;
00539 
00540     if (linear_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
00541         return SRC_ERR_NO_ERROR ;
00542 
00543     return SRC_ERR_BAD_CONVERTER ;
00544 } /* psrc_set_converter */
00545 

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.