+++ /dev/null
-
-/*
- * Error comparison vs double preceision sin() in x86 architecture by 4G points check (round) :
- * ave cos err = 0.038109, ave sin err = 0.000000, max cos err : 4.109593, min cos err : -4.139676, max sin err : 4.139676, min sin err : -4.139676
- * stddev cos err = 0.935760, stddev sin err = 0.936535,
- *
- * Error comparison vs double preceision sin() in x86 architecture by 4G points check (truncate):
- * ave cos err = -1.272776, ave sin err = 0.000000, max cos err : 3.311013, min cos err : -6.006406, max sin err : 6.006406, min sin err : -6.006406
- * stddev cos err = 1.324925, stddev sin err = 1.837222,
- *
- *
- */
-
-#include "fx32_nco.h"
-
-static fract32 ch[33] =
-{
- 2147483647 ,
- 2144896910 ,
- 2137142927 ,
- 2124240380 ,
- 2106220352 ,
- 2083126254 ,
- 2055013723 ,
- 2021950484 ,
- 1984016189 ,
- 1941302225 ,
- 1893911494 ,
- 1841958164 ,
- 1785567396 ,
- 1724875040 ,
- 1660027308 ,
- 1591180426 ,
- 1518500250 ,
- 1442161874 ,
- 1362349204 ,
- 1279254516 ,
- 1193077991 ,
- 1104027237 ,
- 1012316784 ,
- 918167572 ,
- 821806413 ,
- 723465451 ,
- 623381598 ,
- 521795963 ,
- 418953276 ,
- 315101295 ,
- 210490206 ,
- 105372028,
- 0
-
-};
-
-
-static fract32 cm[64]=
-{
- 2147483647 ,
- 2147483016 ,
- 2147481121 ,
- 2147477963 ,
- 2147473542 ,
- 2147467857 ,
- 2147460908 ,
- 2147452697 ,
- 2147443222 ,
- 2147432484 ,
- 2147420483 ,
- 2147407218 ,
- 2147392690 ,
- 2147376899 ,
- 2147359845 ,
- 2147341527 ,
- 2147321946 ,
- 2147301102 ,
- 2147278995 ,
- 2147255625 ,
- 2147230991 ,
- 2147205094 ,
- 2147177934 ,
- 2147149511 ,
- 2147119825 ,
- 2147088876 ,
- 2147056664 ,
- 2147023188 ,
- 2146988450 ,
- 2146952448 ,
- 2146915184 ,
- 2146876656 ,
- 2146836866 ,
- 2146795813 ,
- 2146753497 ,
- 2146709917 ,
- 2146665076 ,
- 2146618971 ,
- 2146571603 ,
- 2146522973 ,
- 2146473080 ,
- 2146421924 ,
- 2146369505 ,
- 2146315824 ,
- 2146260881 ,
- 2146204674 ,
- 2146147205 ,
- 2146088474 ,
- 2146028480 ,
- 2145967224 ,
- 2145904705 ,
- 2145840924 ,
- 2145775880 ,
- 2145709574 ,
- 2145642006 ,
- 2145573176 ,
- 2145503083 ,
- 2145431729 ,
- 2145359112 ,
- 2145285233 ,
- 2145210092 ,
- 2145133690 ,
- 2145056025 ,
- 2144977098
-
-};
-
-static fract32 sm[64]=
-{
- 0 ,
- 1647099 ,
- 3294197 ,
- 4941294 ,
- 6588387 ,
- 8235476 ,
- 9882561 ,
- 11529640 ,
- 13176712 ,
- 14823776 ,
- 16470832 ,
- 18117878 ,
- 19764913 ,
- 21411936 ,
- 23058947 ,
- 24705945 ,
- 26352928 ,
- 27999895 ,
- 29646846 ,
- 31293780 ,
- 32940695 ,
- 34587590 ,
- 36234466 ,
- 37881320 ,
- 39528151 ,
- 41174960 ,
- 42821744 ,
- 44468503 ,
- 46115236 ,
- 47761942 ,
- 49408620 ,
- 51055268 ,
- 52701887 ,
- 54348475 ,
- 55995030 ,
- 57641553 ,
- 59288042 ,
- 60934496 ,
- 62580914 ,
- 64227295 ,
- 65873638 ,
- 67519943 ,
- 69166208 ,
- 70812432 ,
- 72458615 ,
- 74104755 ,
- 75750851 ,
- 77396903 ,
- 79042909 ,
- 80688869 ,
- 82334782 ,
- 83980645 ,
- 85626460 ,
- 87272224 ,
- 88917937 ,
- 90563597 ,
- 92209205 ,
- 93854758 ,
- 95500255 ,
- 97145697 ,
- 98791081 ,
- 100436408 ,
- 102081675 ,
- 103726882
-
-};
-
-static void fract32_sincos( fract32 angle, fract32 *c, fract32 *s )
-{
- int index_h, index_m, index_l;
- int minus, secondhalf;
- fract32 cos, sin, sl,cl, temp;
-
- // -pi is the special case.
- if ( (int)angle == LONG_MIN )
- {
- *c = LONG_MIN; // cos(-pi) = -1. 32bit for blackfin
- *s = 0; // sin( pi ) = 0;
- return;
- }
-
- // when the angle is negative, fold it to positive.
- if ( (int)angle < 0 )
- {
- angle = -angle;
- minus = 1;
- }
- else
- minus = 0;
-
- // 角が第二象限の場合には第一象限に縮退させる
- secondhalf = angle > LONG_MAX/2;
- angle -= (LONG_MAX/2);
-
- index_l = angle & 0x7FFFF;
- index_m = ( angle >> 19 ) & 0x3F;
- index_h = ( angle >> 25 ) & 0x1F;
-
- cos =
- sub_fr1x32(
- mult_fr1x32x32(ch[index_h],cm[index_m]), /* sin * sin */
- mult_fr1x32x32(ch[32-index_h],sm[index_m]) /* cos * cos */
- );
- sin =
- add_fr1x32(
- mult_fr1x32x32(ch[32-index_h],cm[index_m]), /* sin * cos */
- mult_fr1x32x32(ch[index_h],sm[index_m]) /* cos * sin */
- );
-
- /*
- * slは微小角index_lにpiをかけて得たsin(index_l)の近似値である
- * 全周の1/2^13においては誤差は±0.5以下になる。
- */
- sl = mult_fr1x32x32(index_l*4,1686629713 );
- /*
- * slは微小角index_lにをもとにindex_l^2*612で求めたcos(index_l)の近似値である
- */
-
- cl = 0x7FFFFFFF - mult_fr1x32x32(
- mult_fr1x32x32( index_l<<12, index_l<<12),
- 630
- );
-
- *c= sub_fr1x32(
- mult_fr1x32x32(cos,cl),
- mult_fr1x32x32(sin,sl)
- );
- *s = add_fr1x32(
- mult_fr1x32x32(sin,cl),
- mult_fr1x32x32(cos,sl)
- );
-
-
- // 第二象限の場合には値の入れ替えを行う
- if (secondhalf)
- {
- temp = *c;
- *c = -*s;
- *s = temp;
- }
- // 元々の角が負だった場合には、正弦の値を反転する(奇関数なので)
- if ( minus )
- *s = - *s;
-}
-
- /*
- * Set up the nco structure with given frequency. The initial phase is 0;
- */
-void fr32_nco_init ( TNCO * nco, fract32 frequency)
-{
- fr32_nco_set_freq( nco, frequency);
- fr32_nco_set_phase( nco, 0);
-}
-
- /*
- * Change the frequenc of nco.
- */
-void fr32_nco_set_freq( TNCO * nco, fract32 frequency)
-{
- nco->frequency = frequency;
-
-}
-
- /*
- * retrieve the current frequency of nco
- */
-fract32 fr32_nco_get_freq( TNCO * nco)
-{
- return nco->frequency;
-}
-
- /*
- * Change the phase of nco.
- */
-void fr32_nco_set_phase( TNCO * nco, fract32 phase)
-{
- nco->phase = phase;
-}
-
- /*
- * Retrieve the phase of nco.
- */
-fract32 fr32_nco_get_phase( TNCO * nco)
-{
- return nco->phase;
-}
-
-
-void fr32_nco( TNCO *nco, fract32 c[], fract32 s[], int count )
-{
- int i;
-
- for ( i=0; i<count; i++){
- fract32_sincos( fr32_nco_get_phase(nco), &c[i], &s[i] );
- fr32_nco_set_phase( nco, fr32_nco_get_phase( nco ) + fr32_nco_get_freq( nco ) );
- }
-}
-
+++ /dev/null
-/**
- * \file nco.c
- * \brief Numerically Controlled Oscillator
- * \details
- * Sine/Cosine algorithm by table lookup and approximation.
- *
- * \date 2013/04/21
- * \author takemasa
- */
-
-#ifndef NCO_H_
-#define NCO_H_
-
-#ifdef __i386__
-#include "fract_x86.h"
-#else
-#include <fract.h>
-#endif
-
-#include <limits.h>
-
-/**
- * \brief NCO object type
- * \details
- * An object type of NCO. All NCO initialize parameter and internal state are packed into this object type.
- * Programmer shuld not read/write these values directory.
- *
- * Use fr32_nco_init to initialize this object.
- */
-typedef struct {
- fract32 frequency;
- fract32 phase;
-} TNCO;
-
-/**
- * \brief NCO object initialization
- * \param nco a pointer to the NCO management object variable.
- * \param frequency the frequency
- * \details
- * initialize the given NCO object with parameter frequency.
- * This function have to be called once, before calling fr32_nco.
- * The internal phase is initialized as zero.
- *
- * The frequency parameter specify the incremental value for each sample output.
- * This normalized frequency can be obtained by following formula.
- *
- * \code
- * frequency_parameter = desired_frequency * 2^32 / Fs
- * where Fs is the sampling frequency.
- * \/code
- *
- * For example, if the desired frequency is 1kHz and the Fs is 48kHz, the parameter is
- * 89478485 ( = 1000 * 2^32 / 48000 ).
- *
- * Note : The frequency parameter can be negative value. In this case, the
- * output signal represents the negative frequency.
- *
- *
- */
-extern void fr32_nco_init ( TNCO * nco, fract32 frequency);
-
-extern void fr32_nco_set_freq( TNCO * nco, fract32 frequency);
-extern fract32 fr32_nco_get_freq( TNCO * nco);
-extern void fr32_nco_set_phase( TNCO * nco, fract32 phase);
-extern fract32 fr32_nco_get_phase( TNCO * nco);
-extern void fr32_nco( TNCO *nco, fract32 c[], fract32 s[], int count );
-
-
-#endif /* NCO_H_ */