/[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 319 - (hide annotations) (download) (as text)
Mon Dec 13 00:46:42 2004 UTC (19 years, 3 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 10443 byte(s)
* introduced 'synthesis mode' to reduce the amount of code and conditionals
  for the current synthesis case in the main synthesis loop
* support for MMX and SSE(1) in the core synthesis algorithms (CPU feature
  detection at runtime, only x86 so far)

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     #include "global.h"
28    
29     /// Needed for calculating frequency ratio used to pitch a sample
30     #define TWELVEHUNDREDTH_ROOT_OF_TWO 1.000577789506555
31    
32 schoenebeck 319 enum implementation_t {
33     CPP,
34     ASM_X86_MMX_SSE
35     };
36    
37     class RTMathBase {
38 schoenebeck 53 public:
39     /**
40     * Calculates the frequency ratio for a pitch value given in cents
41     * (assuming equal tempered scale of course, divided into 12
42     * semitones per octave and 100 cents per semitone).
43     *
44     * Note: MAX_PITCH (defined in global.h) has to be defined to an
45     * appropriate value, otherwise the behavior of this function is
46     * undefined, but most probably if MAX_PITCH is too small, the
47     * application will crash due to segmentation fault here.
48     *
49     * @param cents - pitch value in cents (+1200 cents means +1 octave)
50     * @returns frequency ratio (e.g. +2.0 for +1 octave)
51     */
52     inline static double CentsToFreqRatio(double Cents) {
53 schoenebeck 319 int index_int = (int) (Cents); // integer index
54 schoenebeck 53 float index_fract = Cents - index_int; // fractional part of index
55     return pCentsToFreqTable[index_int] + index_fract * (pCentsToFreqTable[index_int+1] - pCentsToFreqTable[index_int]);
56     }
57    
58 schoenebeck 319 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 schoenebeck 53 return (b < a) ? b : a;
233     }
234    
235 schoenebeck 319 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 schoenebeck 53 return (b > a) ? b : a;
256     }
257    
258 schoenebeck 319 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 schoenebeck 53 };
284    
285 schoenebeck 319 /// convenience typedef for using the default implementation (which is CPP)
286     typedef __RTMath<> RTMath;
287    
288 schoenebeck 53 #endif // __RT_MATH_H__

  ViewVC Help
Powered by ViewVC