/[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 361 - (show 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 /***************************************************************************
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 ASM_X86_MMX_SSE
36 };
37
38 class RTMathBase {
39 public:
40 /**
41 * 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 * 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 int index_int = (int) (Cents); // integer index
68 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 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 #if ARCH_X86
93 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 #endif // ARCH_X86
103 }
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 #if ARCH_X86
117 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 #endif // ARCH_X86
128 }
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 #if ARCH_X86
144 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 #endif // ARCH_X86
156 }
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 #if ARCH_X86
169 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 #endif // ARCH_X86
181 }
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 #if ARCH_X86
194 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 #endif // ARCH_X86
206 }
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 #if ARCH_X86
219 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 #endif // ARCH_X86
231 }
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 #if ARCH_X86
244 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 #endif // ARCH_X86
256 }
257 }
258
259 template<class T_a, class T_b> inline static T_a Min(const T_a a, const T_b b) {
260 return (b < a) ? b : a;
261 }
262
263 inline static float Max(const float a, const float b) {
264 switch (IMPL) {
265 case CPP: {
266 return (b > a) ? b : a;
267 }
268 #if ARCH_X86
269 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 #endif // ARCH_X86
281 }
282 }
283
284 template<class T_a, class T_b> inline static T_a Max(const T_a a, const T_b b) {
285 return (b > a) ? b : a;
286 }
287
288 inline static float Fmodf(const float &a, const float &b) {
289 switch (IMPL) {
290 case CPP: {
291 return fmodf(a, b);
292 }
293 #if ARCH_X86
294 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 #endif // ARCH_X86
313 }
314 }
315 };
316
317 /// convenience typedef for using the default implementation (which is CPP)
318 typedef __RTMath<> RTMath;
319
320 #endif // __RT_MATH_H__

  ViewVC Help
Powered by ViewVC