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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (show annotations) (download) (as text)
Sat Dec 25 21:58:58 2004 UTC (19 years, 4 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 11507 byte(s)
* architecture independence fixes, should now compile again for non x86
  systems
* tiny fix of command line switch --version

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
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 <stdint.h>
28 #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 enum implementation_t {
34 CPP
35 #if ARCH_X86
36 ,ASM_X86_MMX_SSE
37 #endif // ARCH_X86
38 };
39
40 class RTMathBase {
41 public:
42 /**
43 * Highly accurate time stamp.
44 */
45 typedef uint32_t time_stamp_t;
46
47 /**
48 * We read the processor's cycle count register as a reference
49 * for the real time. These are of course only abstract values
50 * with arbitrary time entity, but that's not a problem as long
51 * as we calculate relatively.
52 */
53 static time_stamp_t CreateTimeStamp();
54
55 /**
56 * Calculates the frequency ratio for a pitch value given in cents
57 * (assuming equal tempered scale of course, divided into 12
58 * semitones per octave and 100 cents per semitone).
59 *
60 * Note: MAX_PITCH (defined in global.h) has to be defined to an
61 * appropriate value, otherwise the behavior of this function is
62 * undefined, but most probably if MAX_PITCH is too small, the
63 * application will crash due to segmentation fault here.
64 *
65 * @param cents - pitch value in cents (+1200 cents means +1 octave)
66 * @returns frequency ratio (e.g. +2.0 for +1 octave)
67 */
68 inline static double CentsToFreqRatio(double Cents) {
69 int index_int = (int) (Cents); // integer index
70 float index_fract = Cents - index_int; // fractional part of index
71 return pCentsToFreqTable[index_int] + index_fract * (pCentsToFreqTable[index_int+1] - pCentsToFreqTable[index_int]);
72 }
73
74 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;
263 }
264
265 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;
288 }
289
290 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__

  ViewVC Help
Powered by ViewVC