/[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 318 by schoenebeck, Tue Apr 27 09:21:58 2004 UTC revision 319 by schoenebeck, Mon Dec 13 00:46:42 2004 UTC
# Line 29  Line 29 
29  /// Needed for calculating frequency ratio used to pitch a sample  /// Needed for calculating frequency ratio used to pitch a sample
30  #define TWELVEHUNDREDTH_ROOT_OF_TWO     1.000577789506555  #define TWELVEHUNDREDTH_ROOT_OF_TWO     1.000577789506555
31    
32  /** Real Time Math  enum implementation_t {
33   *      CPP,
34   * Math functions for real time operation.      ASM_X86_MMX_SSE
35   */  };
 class RTMath {  
     public:  
         /**  
          * Converts a double to integer type.  
          */  
         inline static int DoubleToInt(double f) {  
             #if ARCH_X86  
             int i;  
             __asm__ ("fistl %0" : "=m"(i) : "st"(f - 0.5) );  
             return i;  
             #else  
             return (int) f;  
             #endif // ARCH_X86  
         }  
36    
37    class RTMathBase {
38        public:
39          /**          /**
40           * Calculates the frequency ratio for a pitch value given in cents           * Calculates the frequency ratio for a pitch value given in cents
41           * (assuming equal tempered scale of course, divided into 12           * (assuming equal tempered scale of course, divided into 12
# Line 62  class RTMath { Line 50  class RTMath {
50           * @returns  frequency ratio (e.g. +2.0 for +1 octave)           * @returns  frequency ratio (e.g. +2.0 for +1 octave)
51           */           */
52          inline static double CentsToFreqRatio(double Cents) {          inline static double CentsToFreqRatio(double Cents) {
53              int   index_int   = DoubleToInt(Cents); // integer index              int   index_int   = (int) (Cents);      // integer index
54              float index_fract = Cents - index_int;  // fractional part of index              float index_fract = Cents - index_int;  // fractional part of index
55              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]);
56          }          }
57    
58          template<class T_a, class T_b> inline static T_a Min(T_a a, T_b b) {      private:
59            static float  CentsToFreqTable[MAX_PITCH * 1200 * 2 + 1];
60            static float* pCentsToFreqTable;
61    
62            static float* InitCentsToFreqTable();
63    };
64    
65    /** Real Time Math
66     *
67     * Math functions for real time operation.
68     */
69    template<implementation_t IMPL = CPP>
70    class __RTMath : public RTMathBase {
71        public:
72            // conversion using truncate
73            inline static int Int(const float a) {
74                switch (IMPL) {
75                    case CPP: {
76                        return (int) a;
77                    }
78                    case ASM_X86_MMX_SSE: {
79                        int ret;
80                        asm (
81                            "cvttss2si %1, %0  # convert to int\n\t"
82                            : "=r" (ret)
83                            : "m" (a)
84                        );
85                        return ret;
86                    }
87                }
88            }
89    
90            //for doubles and everything else except floats
91            template<class T_a> inline static int Int(const T_a a) {
92                return (int) a;
93            }
94    
95            inline static float Float(const int a) {
96                switch (IMPL) {
97                    case CPP: {
98                        return (float) a;
99                    }
100                    case ASM_X86_MMX_SSE: {
101                        float ret;
102                        asm (
103                            "cvtsi2ss %1, %%xmm0  # convert to float\n\t"
104                            "movss    %%xmm0,%0   # output\n\t"
105                            : "=m" (ret)
106                            : "r" (a)
107                        );
108                        return ret;
109                    }
110                }
111            }
112    
113    #if 0
114            //for everything except ints
115            template<class T_a> inline static float Float(T_a a) {
116                return (float) a;
117            }
118    #endif
119    
120            inline static float Sum(const float& a, const float& b) {
121                switch (IMPL) {
122                    case CPP: {
123                        return (a + b);
124                    }
125                    case ASM_X86_MMX_SSE: {
126                        float ret;
127                        asm (
128                            "movss    %1, %%xmm0  # load a\n\t"
129                            "addss    %2, %%xmm0  # a + b\n\t"
130                            "movss    %%xmm0, %0  # output\n\t"
131                            : "=m" (ret)
132                            : "m" (a), "m" (b)
133                        );
134                        return ret;
135                    }
136                }
137            }
138    
139            template<class T_a, class T_b> inline static T_a Sum(const T_a a, const T_b b) {
140                return (a + b);
141            }
142    
143            inline static float Sub(const float& a, const float& b) {
144                switch (IMPL) {
145                    case CPP: {
146                        return (a - b);
147                    }
148                    case ASM_X86_MMX_SSE: {
149                        float ret;
150                        asm (
151                            "movss    %1, %%xmm0  # load a\n\t"
152                            "subss    %2, %%xmm0  # a - b\n\t"
153                            "movss    %%xmm0, %0  # output\n\t"
154                            : "=m" (ret)
155                            : "m" (a), "m" (b)
156                        );
157                        return ret;
158                    }
159                }
160            }
161    
162            template<class T_a, class T_b> inline static T_a Sub(const T_a a, const T_b b) {
163                return (a - b);
164            }
165    
166            inline static float Mul(const float a, const float b) {
167                switch (IMPL) {
168                    case CPP: {
169                        return (a * b);
170                    }
171                    case ASM_X86_MMX_SSE: {
172                        float ret;
173                        asm (
174                            "movss    %1, %%xmm0  # load a\n\t"
175                            "mulss    %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                }
183            }
184    
185            template<class T_a, class T_b> inline static T_a Mul(const T_a a, const T_b b) {
186                return (a * b);
187            }
188    
189            inline static float Div(const float a, const float b) {
190                switch (IMPL) {
191                    case CPP: {
192                        return (a / b);
193                    }
194                    case ASM_X86_MMX_SSE: {
195                        float ret;
196                        asm (
197                            "movss    %1, %%xmm0  # load a\n\t"
198                            "divss    %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                }
206            }
207    
208            template<class T_a, class T_b> inline static T_a Div(const T_a a, const T_b b) {
209                return (a / b);
210            }
211    
212            inline static float Min(const float a, const float b) {
213                switch (IMPL) {
214                    case CPP: {
215                        return (b < a) ? b : a;
216                    }
217                    case ASM_X86_MMX_SSE: {
218                        float ret;
219                        asm (
220                            "movss    %1, %%xmm0  # load a\n\t"
221                            "minss    %2, %%xmm0  # Minimum(a, b)\n\t"
222                            "movss    %%xmm0, %0  # output\n\t"
223                            : "=m" (ret)
224                            : "m" (a), "m" (b)
225                        );
226                        return ret;
227                    }
228                }
229            }
230    
231            template<class T_a, class T_b> inline static T_a Min(const T_a a, const T_b b) {
232              return (b < a) ? b : a;              return (b < a) ? b : a;
233          }          }
234    
235          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) {
236                switch (IMPL) {
237                    case CPP: {
238                        return (b > a) ? b : a;
239                    }
240                    case ASM_X86_MMX_SSE: {
241                        float ret;
242                        asm (
243                            "movss    %1, %%xmm0  # load a\n\t"
244                            "maxss    %2, %%xmm0  # Maximum(a, b)\n\t"
245                            "movss    %%xmm0, %0  # output\n\t"
246                            : "=m" (ret)
247                            : "m" (a), "m" (b)
248                        );
249                        return ret;
250                    }
251                }
252            }
253    
254            template<class T_a, class T_b> inline static T_a Max(const T_a a, const T_b b) {
255              return (b > a) ? b : a;              return (b > a) ? b : a;
256          }          }
     private:  
         static float  CentsToFreqTable[MAX_PITCH * 1200 * 2 + 1];  
         static float* pCentsToFreqTable;  
257    
258          static float* InitCentsToFreqTable();          inline static float Fmodf(const float &a, const float &b) {
259                switch (IMPL) {
260                    case CPP: {
261                        return fmodf(a, b);
262                    }
263                    case ASM_X86_MMX_SSE: {
264                        float ret;
265                        asm (
266                            "movss    %1, %%xmm0  # load a\n\t"
267                            "movss    %2, %%xmm1  # load b\n\t"
268                            "movss    %%xmm0,%%xmm2\n\t"
269                            "divss    %%xmm1, %%xmm2  # xmm2 = a / b\n\t"
270                            "cvttss2si %%xmm2, %%ecx  #convert to int\n\t"
271                            "cvtsi2ss %%ecx, %%xmm2  #convert back to float\n\t"
272                            "mulss    %%xmm1, %%xmm2  # xmm2 = b * int(a/b)\n\t"
273                            "subss    %%xmm2, %%xmm0  #sub a\n\t"
274                            "movss    %%xmm0, %0  # output\n\t"
275                            : "=m" (ret)
276                            : "m" (a), "m" (b)
277                            : "%ecx"
278                        );
279                        return ret;
280                    }
281                }
282            }
283  };  };
284    
285    /// convenience typedef for using the default implementation (which is CPP)
286    typedef __RTMath<> RTMath;
287    
288  #endif // __RT_MATH_H__  #endif // __RT_MATH_H__

Legend:
Removed from v.318  
changed lines
  Added in v.319

  ViewVC Help
Powered by ViewVC