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

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

  ViewVC Help
Powered by ViewVC