CMSIS DSP library

Dependents:   KL25Z_FFT_Demo Hat_Board_v5_1 KL25Z_FFT_Demo_tony KL25Z_FFT_Demo_tony ... more

Fork of mbed-dsp by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_sin_f32.c Source File

arm_sin_f32.c

00001 /* ----------------------------------------------------------------------    
00002 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.    
00003 *    
00004 * $Date:        17. January 2013
00005 * $Revision:    V1.4.1
00006 *    
00007 * Project:      CMSIS DSP Library    
00008 * Title:        arm_sin_f32.c    
00009 *    
00010 * Description:  Fast sine calculation for floating-point values.   
00011 *    
00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
00013 *  
00014 * Redistribution and use in source and binary forms, with or without 
00015 * modification, are permitted provided that the following conditions
00016 * are met:
00017 *   - Redistributions of source code must retain the above copyright
00018 *     notice, this list of conditions and the following disclaimer.
00019 *   - Redistributions in binary form must reproduce the above copyright
00020 *     notice, this list of conditions and the following disclaimer in
00021 *     the documentation and/or other materials provided with the 
00022 *     distribution.
00023 *   - Neither the name of ARM LIMITED nor the names of its contributors
00024 *     may be used to endorse or promote products derived from this
00025 *     software without specific prior written permission.
00026 *
00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00036 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00038 * POSSIBILITY OF SUCH DAMAGE. 
00039 * -------------------------------------------------------------------- */
00040 
00041 #include "arm_math.h"
00042 
00043 /**    
00044  * @ingroup groupFastMath    
00045  */
00046 
00047 /**    
00048  * @defgroup sin Sine    
00049  *    
00050  * Computes the trigonometric sine function using a combination of table lookup   
00051  * and cubic interpolation.  There are separate functions for   
00052  * Q15, Q31, and floating-point data types.   
00053  * The input to the floating-point version is in radians while the   
00054  * fixed-point Q15 and Q31 have a scaled input with the range   
00055  * [0 +0.9999] mapping to [0 2*pi).  The fixed-point range is chosen so that a
00056  * value of 2*pi wraps around to 0.
00057  *   
00058  * The implementation is based on table lookup using 256 values together with cubic interpolation.   
00059  * The steps used are:   
00060  *  -# Calculation of the nearest integer table index   
00061  *  -# Fetch the four table values a, b, c, and d     
00062  *  -# Compute the fractional portion (fract) of the table index.   
00063  *  -# Calculation of wa, wb, wc, wd    
00064  *  -# The final result equals <code>a*wa + b*wb + c*wc + d*wd</code>   
00065  *   
00066  * where   
00067  * <pre>    
00068  *    a=Table[index-1];    
00069  *    b=Table[index+0];    
00070  *    c=Table[index+1];    
00071  *    d=Table[index+2];    
00072  * </pre>   
00073  * and   
00074  * <pre>    
00075  *    wa=-(1/6)*fract.^3 + (1/2)*fract.^2 - (1/3)*fract;    
00076  *    wb=(1/2)*fract.^3 - fract.^2 - (1/2)*fract + 1;    
00077  *    wc=-(1/2)*fract.^3+(1/2)*fract.^2+fract;    
00078  *    wd=(1/6)*fract.^3 - (1/6)*fract;    
00079  * </pre>    
00080  */
00081 
00082 /**    
00083  * @addtogroup sin    
00084  * @{    
00085  */
00086 
00087 
00088 /**   
00089  * \par    
00090  * Example code for the generation of the floating-point sine table:
00091  * <pre>
00092  * tableSize = 256;    
00093  * for(n = -1; n < (tableSize + 1); n++)    
00094  * {    
00095  *  sinTable[n+1]=sin(2*pi*n/tableSize);    
00096  * }</pre>    
00097  * \par    
00098  * where pi value is  3.14159265358979    
00099  */
00100 
00101 static const float32_t sinTable [259] = {
00102   -0.024541229009628296f, 0.000000000000000000f, 0.024541229009628296f,
00103   0.049067676067352295f, 0.073564566671848297f, 0.098017141222953796f,
00104   0.122410677373409270f, 0.146730467677116390f,
00105   0.170961886644363400f, 0.195090323686599730f, 0.219101235270500180f,
00106   0.242980182170867920f, 0.266712754964828490f, 0.290284663438797000f,
00107   0.313681751489639280f, 0.336889863014221190f,
00108   0.359895050525665280f, 0.382683426141738890f, 0.405241310596466060f,
00109   0.427555084228515630f, 0.449611335992813110f, 0.471396744251251220f,
00110   0.492898195981979370f, 0.514102756977081300f,
00111   0.534997642040252690f, 0.555570244789123540f, 0.575808167457580570f,
00112   0.595699310302734380f, 0.615231573581695560f, 0.634393274784088130f,
00113   0.653172850608825680f, 0.671558976173400880f,
00114   0.689540565013885500f, 0.707106769084930420f, 0.724247097969055180f,
00115   0.740951120853424070f, 0.757208824157714840f, 0.773010432720184330f,
00116   0.788346409797668460f, 0.803207516670227050f,
00117   0.817584812641143800f, 0.831469595432281490f, 0.844853579998016360f,
00118   0.857728600502014160f, 0.870086967945098880f, 0.881921291351318360f,
00119   0.893224298954010010f, 0.903989315032958980f,
00120   0.914209783077239990f, 0.923879504203796390f, 0.932992815971374510f,
00121   0.941544055938720700f, 0.949528157711029050f, 0.956940352916717530f,
00122   0.963776051998138430f, 0.970031261444091800f,
00123   0.975702106952667240f, 0.980785250663757320f, 0.985277652740478520f,
00124   0.989176511764526370f, 0.992479562759399410f, 0.995184719562530520f,
00125   0.997290432453155520f, 0.998795449733734130f,
00126   0.999698817729949950f, 1.000000000000000000f, 0.999698817729949950f,
00127   0.998795449733734130f, 0.997290432453155520f, 0.995184719562530520f,
00128   0.992479562759399410f, 0.989176511764526370f,
00129   0.985277652740478520f, 0.980785250663757320f, 0.975702106952667240f,
00130   0.970031261444091800f, 0.963776051998138430f, 0.956940352916717530f,
00131   0.949528157711029050f, 0.941544055938720700f,
00132   0.932992815971374510f, 0.923879504203796390f, 0.914209783077239990f,
00133   0.903989315032958980f, 0.893224298954010010f, 0.881921291351318360f,
00134   0.870086967945098880f, 0.857728600502014160f,
00135   0.844853579998016360f, 0.831469595432281490f, 0.817584812641143800f,
00136   0.803207516670227050f, 0.788346409797668460f, 0.773010432720184330f,
00137   0.757208824157714840f, 0.740951120853424070f,
00138   0.724247097969055180f, 0.707106769084930420f, 0.689540565013885500f,
00139   0.671558976173400880f, 0.653172850608825680f, 0.634393274784088130f,
00140   0.615231573581695560f, 0.595699310302734380f,
00141   0.575808167457580570f, 0.555570244789123540f, 0.534997642040252690f,
00142   0.514102756977081300f, 0.492898195981979370f, 0.471396744251251220f,
00143   0.449611335992813110f, 0.427555084228515630f,
00144   0.405241310596466060f, 0.382683426141738890f, 0.359895050525665280f,
00145   0.336889863014221190f, 0.313681751489639280f, 0.290284663438797000f,
00146   0.266712754964828490f, 0.242980182170867920f,
00147   0.219101235270500180f, 0.195090323686599730f, 0.170961886644363400f,
00148   0.146730467677116390f, 0.122410677373409270f, 0.098017141222953796f,
00149   0.073564566671848297f, 0.049067676067352295f,
00150   0.024541229009628296f, 0.000000000000000122f, -0.024541229009628296f,
00151   -0.049067676067352295f, -0.073564566671848297f, -0.098017141222953796f,
00152   -0.122410677373409270f, -0.146730467677116390f,
00153   -0.170961886644363400f, -0.195090323686599730f, -0.219101235270500180f,
00154   -0.242980182170867920f, -0.266712754964828490f, -0.290284663438797000f,
00155   -0.313681751489639280f, -0.336889863014221190f,
00156   -0.359895050525665280f, -0.382683426141738890f, -0.405241310596466060f,
00157   -0.427555084228515630f, -0.449611335992813110f, -0.471396744251251220f,
00158   -0.492898195981979370f, -0.514102756977081300f,
00159   -0.534997642040252690f, -0.555570244789123540f, -0.575808167457580570f,
00160   -0.595699310302734380f, -0.615231573581695560f, -0.634393274784088130f,
00161   -0.653172850608825680f, -0.671558976173400880f,
00162   -0.689540565013885500f, -0.707106769084930420f, -0.724247097969055180f,
00163   -0.740951120853424070f, -0.757208824157714840f, -0.773010432720184330f,
00164   -0.788346409797668460f, -0.803207516670227050f,
00165   -0.817584812641143800f, -0.831469595432281490f, -0.844853579998016360f,
00166   -0.857728600502014160f, -0.870086967945098880f, -0.881921291351318360f,
00167   -0.893224298954010010f, -0.903989315032958980f,
00168   -0.914209783077239990f, -0.923879504203796390f, -0.932992815971374510f,
00169   -0.941544055938720700f, -0.949528157711029050f, -0.956940352916717530f,
00170   -0.963776051998138430f, -0.970031261444091800f,
00171   -0.975702106952667240f, -0.980785250663757320f, -0.985277652740478520f,
00172   -0.989176511764526370f, -0.992479562759399410f, -0.995184719562530520f,
00173   -0.997290432453155520f, -0.998795449733734130f,
00174   -0.999698817729949950f, -1.000000000000000000f, -0.999698817729949950f,
00175   -0.998795449733734130f, -0.997290432453155520f, -0.995184719562530520f,
00176   -0.992479562759399410f, -0.989176511764526370f,
00177   -0.985277652740478520f, -0.980785250663757320f, -0.975702106952667240f,
00178   -0.970031261444091800f, -0.963776051998138430f, -0.956940352916717530f,
00179   -0.949528157711029050f, -0.941544055938720700f,
00180   -0.932992815971374510f, -0.923879504203796390f, -0.914209783077239990f,
00181   -0.903989315032958980f, -0.893224298954010010f, -0.881921291351318360f,
00182   -0.870086967945098880f, -0.857728600502014160f,
00183   -0.844853579998016360f, -0.831469595432281490f, -0.817584812641143800f,
00184   -0.803207516670227050f, -0.788346409797668460f, -0.773010432720184330f,
00185   -0.757208824157714840f, -0.740951120853424070f,
00186   -0.724247097969055180f, -0.707106769084930420f, -0.689540565013885500f,
00187   -0.671558976173400880f, -0.653172850608825680f, -0.634393274784088130f,
00188   -0.615231573581695560f, -0.595699310302734380f,
00189   -0.575808167457580570f, -0.555570244789123540f, -0.534997642040252690f,
00190   -0.514102756977081300f, -0.492898195981979370f, -0.471396744251251220f,
00191   -0.449611335992813110f, -0.427555084228515630f,
00192   -0.405241310596466060f, -0.382683426141738890f, -0.359895050525665280f,
00193   -0.336889863014221190f, -0.313681751489639280f, -0.290284663438797000f,
00194   -0.266712754964828490f, -0.242980182170867920f,
00195   -0.219101235270500180f, -0.195090323686599730f, -0.170961886644363400f,
00196   -0.146730467677116390f, -0.122410677373409270f, -0.098017141222953796f,
00197   -0.073564566671848297f, -0.049067676067352295f,
00198   -0.024541229009628296f, -0.000000000000000245f, 0.024541229009628296f
00199 };
00200 
00201 
00202 /**   
00203  * @brief  Fast approximation to the trigonometric sine function for floating-point data.   
00204  * @param[in] x input value in radians.   
00205  * @return  sin(x).   
00206  */
00207 
00208 float32_t arm_sin_f32(
00209   float32_t x)
00210 {
00211   float32_t sinVal, fract, in;                   /* Temporary variables for input, output */
00212   int32_t index;                                 /* Index variable */
00213   uint32_t tableSize = (uint32_t) TABLE_SIZE;    /* Initialise tablesize */
00214   float32_t wa, wb, wc, wd;                      /* Cubic interpolation coefficients */
00215   float32_t a, b, c, d;                          /* Four nearest output values */
00216   float32_t *tablePtr;                           /* Pointer to table */
00217   int32_t n;
00218   float32_t fractsq, fractby2, fractby6, fractby3, fractsqby2;
00219   float32_t oneminusfractby2;
00220   float32_t frby2xfrsq, frby6xfrsq;
00221 
00222   /* input x is in radians */
00223   /* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi */
00224   in = x * 0.159154943092f;
00225 
00226   /* Calculation of floor value of input */
00227   n = (int32_t) in;
00228 
00229   /* Make negative values towards -infinity */
00230   if(x < 0.0f)
00231   {
00232     n = n - 1;
00233   }
00234 
00235   /* Map input value to [0 1] */
00236   in = in - (float32_t) n;
00237 
00238   /* Calculation of index of the table */
00239   index = (uint32_t) (tableSize * in);
00240 
00241   /* fractional value calculation */
00242   fract = ((float32_t) tableSize * in) - (float32_t) index;
00243 
00244   /* Checking min and max index of table */
00245   if(index < 0)
00246   {
00247     index = 0;
00248   }
00249   else if(index > 256)
00250   {
00251     index = 256;
00252   }
00253 
00254   /* Initialise table pointer */
00255   tablePtr = (float32_t *) & sinTable [index];
00256 
00257   /* Read four nearest values of input value from the sin table */
00258   a = tablePtr[0];
00259   b = tablePtr[1];
00260   c = tablePtr[2];
00261   d = tablePtr[3];
00262 
00263   /* Cubic interpolation process */
00264   fractsq = fract * fract;
00265   fractby2 = fract * 0.5f;
00266   fractby6 = fract * 0.166666667f;
00267   fractby3 = fract * 0.3333333333333f;
00268   fractsqby2 = fractsq * 0.5f;
00269   frby2xfrsq = (fractby2) * fractsq;
00270   frby6xfrsq = (fractby6) * fractsq;
00271   oneminusfractby2 = 1.0f - fractby2;
00272   wb = fractsqby2 - fractby3;
00273   wc = (fractsqby2 + fract);
00274   wa = wb - frby6xfrsq;
00275   wb = frby2xfrsq - fractsq;
00276   sinVal = wa * a;
00277   wc = wc - frby2xfrsq;
00278   wd = (frby6xfrsq) - fractby6;
00279   wb = wb + oneminusfractby2;
00280 
00281   /* Calculate sin value */
00282   sinVal = (sinVal + (b * wb)) + ((c * wc) + (d * wd));
00283 
00284   /* Return the output value */
00285   return (sinVal);
00286 
00287 }
00288 
00289 /**    
00290  * @} end of sin group    
00291  */