/[svn]/linuxsampler/trunk/src/common/RTMath.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/RTMath.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 56 by schoenebeck, Tue Apr 27 09:21:58 2004 UTC revision 361 by schoenebeck, Wed Feb 9 01:22:18 2005 UTC
# Line 24  Line 24 
24  #define __RT_MATH_H__  #define __RT_MATH_H__
25    
26  #include <math.h>  #include <math.h>
27    #include <stdint.h>
28  #include "global.h"  #include "global.h"
29    
30  /// Needed for calculating frequency ratio used to pitch a sample  /// Needed for calculating frequency ratio used to pitch a sample
31  #define TWELVEHUNDREDTH_ROOT_OF_TWO     1.000577789506555  #define TWELVEHUNDREDTH_ROOT_OF_TWO     1.000577789506555
32    
33  /** Real Time Math  enum implementation_t {
34   *      CPP,
35   * Math functions for real time operation.      ASM_X86_MMX_SSE
36   */  };
37  class RTMath {  
38    class RTMathBase {
39      public:      public:
40          /**          /**
41           * Converts a double to integer type.           * Highly accurate time stamp.
42           */           */
43          inline static int DoubleToInt(double f) {          typedef uint32_t time_stamp_t;
44              #if ARCH_X86  
45              int i;          /**
46              __asm__ ("fistl %0" : "=m"(i) : "st"(f - 0.5) );           * We read the processor's cycle count register as a reference
47              return i;           * for the real time. These are of course only abstract values
48              #else           * with arbitrary time entity, but that's not a problem as long
49              return (int) f;           * as we calculate relatively.
50              #endif // ARCH_X86           */
51          }          static time_stamp_t CreateTimeStamp();
52    
53          /**          /**
54           * Calculates the frequency ratio for a pitch value given in cents           * Calculates the frequency ratio for a pitch value given in cents
# Line 62  class RTMath { Line 64  class RTMath {
64           * @returns  frequency ratio (e.g. +2.0 for +1 octave)           * @returns  frequency ratio (e.g. +2.0 for +1 octave)
65           */           */
66          inline static double CentsToFreqRatio(double Cents) {          inline static double CentsToFreqRatio(double Cents) {
67              int   index_int   = DoubleToInt(Cents); // integer index              int   index_int   = (int) (Cents);      // integer index
68              float index_fract = Cents - index_int;  // fractional part of index              float index_fract = Cents - index_int;  // fractional part of index
69              return pCentsToFreqTable[index_int] + index_fract * (pCentsToFreqTable[index_int+1] - pCentsToFreqTable[index_int]);              return pCentsToFreqTable[index_int] + index_fract * (pCentsToFreqTable[index_int+1] - pCentsToFreqTable[index_int]);
70          }          }
71    
72          template<class T_a, class T_b> inline static T_a Min(T_a a, T_b b) {      private:
73            static float  CentsToFreqTable[MAX_PITCH * 1200 * 2 + 1];
74            static float* pCentsToFreqTable;
75    
76            static float* InitCentsToFreqTable();
77    };
78    
79    /** Real Time Math
80     *
81     * Math functions for real time operation.
82     */
83    template<implementation_t IMPL = CPP>
84    class __RTMath : public RTMathBase {
85        public:
86            // conversion using truncate
87            inline static int Int(const float a) {
88                switch (IMPL) {
89                    case CPP: {
90                        return (int) a;
91                    }
92                    #if ARCH_X86
93                    case ASM_X86_MMX_SSE: {
94                        int ret;
95                        asm (
96                            "cvttss2si %1, %0  # convert to int\n\t"
97                            : "=r" (ret)
98                            : "m" (a)
99                        );
100                        return ret;
101                    }
102                    #endif // ARCH_X86
103                }
104            }
105    
106            //for doubles and everything else except floats
107            template<class T_a> inline static int Int(const T_a a) {
108                return (int) a;
109            }
110    
111            inline static float Float(const int a) {
112                switch (IMPL) {
113                    case CPP: {
114                        return (float) a;
115                    }
116                    #if ARCH_X86
117                    case ASM_X86_MMX_SSE: {
118                        float ret;
119                        asm (
120                            "cvtsi2ss %1, %%xmm0  # convert to float\n\t"
121                            "movss    %%xmm0,%0   # output\n\t"
122                            : "=m" (ret)
123                            : "r" (a)
124                        );
125                        return ret;
126                    }
127                    #endif // ARCH_X86
128                }
129            }
130    
131    #if 0
132            //for everything except ints
133            template<class T_a> inline static float Float(T_a a) {
134                return (float) a;
135            }
136    #endif
137    
138            inline static float Sum(const float& a, const float& b) {
139                switch (IMPL) {
140                    case CPP: {
141                        return (a + b);
142                    }
143                    #if ARCH_X86
144                    case ASM_X86_MMX_SSE: {
145                        float ret;
146                        asm (
147                            "movss    %1, %%xmm0  # load a\n\t"
148                            "addss    %2, %%xmm0  # a + b\n\t"
149                            "movss    %%xmm0, %0  # output\n\t"
150                            : "=m" (ret)
151                            : "m" (a), "m" (b)
152                        );
153                        return ret;
154                    }
155                    #endif // ARCH_X86
156                }
157            }
158    
159            template<class T_a, class T_b> inline static T_a Sum(const T_a a, const T_b b) {
160                return (a + b);
161            }
162    
163            inline static float Sub(const float& a, const float& b) {
164                switch (IMPL) {
165                    case CPP: {
166                        return (a - b);
167                    }
168                    #if ARCH_X86
169                    case ASM_X86_MMX_SSE: {
170                        float ret;
171                        asm (
172                            "movss    %1, %%xmm0  # load a\n\t"
173                            "subss    %2, %%xmm0  # a - b\n\t"
174                            "movss    %%xmm0, %0  # output\n\t"
175                            : "=m" (ret)
176                            : "m" (a), "m" (b)
177                        );
178                        return ret;
179                    }
180                    #endif // ARCH_X86
181                }
182            }
183    
184            template<class T_a, class T_b> inline static T_a Sub(const T_a a, const T_b b) {
185                return (a - b);
186            }
187    
188            inline static float Mul(const float a, const float b) {
189                switch (IMPL) {
190                    case CPP: {
191                        return (a * b);
192                    }
193                    #if ARCH_X86
194                    case ASM_X86_MMX_SSE: {
195                        float ret;
196                        asm (
197                            "movss    %1, %%xmm0  # load a\n\t"
198                            "mulss    %2, %%xmm0  # a * b\n\t"
199                            "movss    %%xmm0, %0  # output\n\t"
200                            : "=m" (ret)
201                            : "m" (a), "m" (b)
202                        );
203                        return ret;
204                    }
205                    #endif // ARCH_X86
206                }
207            }
208    
209            template<class T_a, class T_b> inline static T_a Mul(const T_a a, const T_b b) {
210                return (a * b);
211            }
212    
213            inline static float Div(const float a, const float b) {
214                switch (IMPL) {
215                    case CPP: {
216                        return (a / b);
217                    }
218                    #if ARCH_X86
219                    case ASM_X86_MMX_SSE: {
220                        float ret;
221                        asm (
222                            "movss    %1, %%xmm0  # load a\n\t"
223                            "divss    %2, %%xmm0  # a / b\n\t"
224                            "movss    %%xmm0, %0  # output\n\t"
225                            : "=m" (ret)
226                            : "m" (a), "m" (b)
227                        );
228                        return ret;
229                    }
230                    #endif // ARCH_X86
231                }
232            }
233    
234            template<class T_a, class T_b> inline static T_a Div(const T_a a, const T_b b) {
235                return (a / b);
236            }
237    
238            inline static float Min(const float a, const float b) {
239                switch (IMPL) {
240                    case CPP: {
241                        return (b < a) ? b : a;
242                    }
243                    #if ARCH_X86
244                    case ASM_X86_MMX_SSE: {
245                        float ret;
246                        asm (
247                            "movss    %1, %%xmm0  # load a\n\t"
248                            "minss    %2, %%xmm0  # Minimum(a, b)\n\t"
249                            "movss    %%xmm0, %0  # output\n\t"
250                            : "=m" (ret)
251                            : "m" (a), "m" (b)
252                        );
253                        return ret;
254                    }
255                    #endif // ARCH_X86
256                }
257            }
258    
259            template<class T_a, class T_b> inline static T_a Min(const T_a a, const T_b b) {
260              return (b < a) ? b : a;              return (b < a) ? b : a;
261          }          }
262    
263          template<class T_a, class T_b> inline static T_a Max(T_a a, T_b b) {          inline static float Max(const float a, const float b) {
264                switch (IMPL) {
265                    case CPP: {
266                        return (b > a) ? b : a;
267                    }
268                    #if ARCH_X86
269                    case ASM_X86_MMX_SSE: {
270                        float ret;
271                        asm (
272                            "movss    %1, %%xmm0  # load a\n\t"
273                            "maxss    %2, %%xmm0  # Maximum(a, b)\n\t"
274                            "movss    %%xmm0, %0  # output\n\t"
275                            : "=m" (ret)
276                            : "m" (a), "m" (b)
277                        );
278                        return ret;
279                    }
280                    #endif // ARCH_X86
281                }
282            }
283    
284            template<class T_a, class T_b> inline static T_a Max(const T_a a, const T_b b) {
285              return (b > a) ? b : a;              return (b > a) ? b : a;
286          }          }
     private:  
         static float  CentsToFreqTable[MAX_PITCH * 1200 * 2 + 1];  
         static float* pCentsToFreqTable;  
287    
288          static float* InitCentsToFreqTable();          inline static float Fmodf(const float &a, const float &b) {
289                switch (IMPL) {
290                    case CPP: {
291                        return fmodf(a, b);
292                    }
293                    #if ARCH_X86
294                    case ASM_X86_MMX_SSE: {
295                        float ret;
296                        asm (
297                            "movss    %1, %%xmm0  # load a\n\t"
298                            "movss    %2, %%xmm1  # load b\n\t"
299                            "movss    %%xmm0,%%xmm2\n\t"
300                            "divss    %%xmm1, %%xmm2  # xmm2 = a / b\n\t"
301                            "cvttss2si %%xmm2, %%ecx  #convert to int\n\t"
302                            "cvtsi2ss %%ecx, %%xmm2  #convert back to float\n\t"
303                            "mulss    %%xmm1, %%xmm2  # xmm2 = b * int(a/b)\n\t"
304                            "subss    %%xmm2, %%xmm0  #sub a\n\t"
305                            "movss    %%xmm0, %0  # output\n\t"
306                            : "=m" (ret)
307                            : "m" (a), "m" (b)
308                            : "%ecx"
309                        );
310                        return ret;
311                    }
312                    #endif // ARCH_X86
313                }
314            }
315  };  };
316    
317    /// convenience typedef for using the default implementation (which is CPP)
318    typedef __RTMath<> RTMath;
319    
320  #endif // __RT_MATH_H__  #endif // __RT_MATH_H__

Legend:
Removed from v.56  
changed lines
  Added in v.361

  ViewVC Help
Powered by ViewVC