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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 361 - (hide annotations) (download) (as text)
Wed Feb 9 01:22:18 2005 UTC (19 years, 2 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 11467 byte(s)
* bunch of fixes for OSX (patch by Stephane Letz)

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 53 * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #ifndef __RT_MATH_H__
24     #define __RT_MATH_H__
25    
26     #include <math.h>
27 schoenebeck 328 #include <stdint.h>
28 schoenebeck 53 #include "global.h"
29    
30     /// Needed for calculating frequency ratio used to pitch a sample
31     #define TWELVEHUNDREDTH_ROOT_OF_TWO 1.000577789506555
32    
33 schoenebeck 319 enum implementation_t {
34 schoenebeck 361 CPP,
35     ASM_X86_MMX_SSE
36 schoenebeck 319 };
37    
38     class RTMathBase {
39 schoenebeck 53 public:
40     /**
41 schoenebeck 328 * Highly accurate time stamp.
42     */
43     typedef uint32_t time_stamp_t;
44    
45     /**
46     * We read the processor's cycle count register as a reference
47     * for the real time. These are of course only abstract values
48     * with arbitrary time entity, but that's not a problem as long
49     * as we calculate relatively.
50     */
51     static time_stamp_t CreateTimeStamp();
52    
53     /**
54 schoenebeck 53 * Calculates the frequency ratio for a pitch value given in cents
55     * (assuming equal tempered scale of course, divided into 12
56     * semitones per octave and 100 cents per semitone).
57     *
58     * Note: MAX_PITCH (defined in global.h) has to be defined to an
59     * appropriate value, otherwise the behavior of this function is
60     * undefined, but most probably if MAX_PITCH is too small, the
61     * application will crash due to segmentation fault here.
62     *
63     * @param cents - pitch value in cents (+1200 cents means +1 octave)
64     * @returns frequency ratio (e.g. +2.0 for +1 octave)
65     */
66     inline static double CentsToFreqRatio(double Cents) {
67 schoenebeck 319 int index_int = (int) (Cents); // integer index
68 schoenebeck 53 float index_fract = Cents - index_int; // fractional part of index
69     return pCentsToFreqTable[index_int] + index_fract * (pCentsToFreqTable[index_int+1] - pCentsToFreqTable[index_int]);
70     }
71    
72 schoenebeck 319 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 schoenebeck 328 #if ARCH_X86
93 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
103 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
117 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
128 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
144 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
156 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
169 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
181 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
194 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
206 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
219 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
231 schoenebeck 319 }
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 schoenebeck 328 #if ARCH_X86
244 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
256 schoenebeck 319 }
257     }
258    
259     template<class T_a, class T_b> inline static T_a Min(const T_a a, const T_b b) {
260 schoenebeck 53 return (b < a) ? b : a;
261     }
262    
263 schoenebeck 319 inline static float Max(const float a, const float b) {
264     switch (IMPL) {
265     case CPP: {
266     return (b > a) ? b : a;
267     }
268 schoenebeck 328 #if ARCH_X86
269 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
281 schoenebeck 319 }
282     }
283    
284     template<class T_a, class T_b> inline static T_a Max(const T_a a, const T_b b) {
285 schoenebeck 53 return (b > a) ? b : a;
286     }
287    
288 schoenebeck 319 inline static float Fmodf(const float &a, const float &b) {
289     switch (IMPL) {
290     case CPP: {
291     return fmodf(a, b);
292     }
293 schoenebeck 328 #if ARCH_X86
294 schoenebeck 319 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 schoenebeck 328 #endif // ARCH_X86
313 schoenebeck 319 }
314     }
315 schoenebeck 53 };
316    
317 schoenebeck 319 /// convenience typedef for using the default implementation (which is CPP)
318     typedef __RTMath<> RTMath;
319    
320 schoenebeck 53 #endif // __RT_MATH_H__

  ViewVC Help
Powered by ViewVC