A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1685 lines 51 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2009 Wincent Balin 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include "plugin.h" 23#include "pdbox.h" 24#include "ctype.h" 25 26#include "PDa/src/m_pd.h" 27#include "PDa/src/s_stuff.h" 28 29 30/* This implementation of strncat is taken from lua plug-in. */ 31 32/* gcc is broken and has a non-SUSv2 compliant internal prototype. 33 * This causes it to warn about a type mismatch here. Ignore it. */ 34char *rb_strncat(char *s, const char *t, size_t n) 35{ 36 char *dest = s; 37 register char *max; 38 s += strlen(s); 39 40 if((max = s + n) == s) 41 goto strncat_fini; 42 43 while(true) 44 { 45 if(!(*s = *t)) 46 break; 47 if(++s == max) 48 break; 49 ++t; 50 51#ifndef WANT_SMALL_STRING_ROUTINES 52 if(!(*s = *t)) 53 break; 54 if(++s == max) 55 break; 56 ++t; 57 if(!(*s = *t)) 58 break; 59 if(++s == max) 60 break; 61 ++t; 62 if(!(*s = *t)) 63 break; 64 if(++s == max) 65 break; 66 ++t; 67#endif 68 } 69 70 *s = 0; 71 72strncat_fini: 73 return dest; 74} 75 76 77/* Implementation of floor, original. */ 78float rb_floor(float value) 79{ 80 /* If value is negative, decrement value to match function's definition. */ 81 if(value < 0.0) 82 { 83 value -= 1.0; 84 } 85 86 /* Truncate fractional part (convert to integer) 87 and afterwards convert back to double. */ 88 return (float) ((int) value); 89} 90 91 92/* Implementation of strtod() and atof(), 93 taken from SanOS (http://www.jbox.dk/sanos/). */ 94static int rb_errno = 0; 95 96double rb_strtod(const char *str, char **endptr) 97{ 98 double number; 99 int exponent; 100 int negative; 101 char *p = (char *) str; 102 double p10; 103 int n; 104 int num_digits; 105 int num_decimals; 106 107 /* Reset Rockbox errno -- W.B. */ 108#ifdef ROCKBOX 109 rb_errno = 0; 110#endif 111 112 // Skip leading whitespace 113 while (isspace(*p)) p++; 114 115 // Handle optional sign 116 negative = 0; 117 switch (*p) 118 { 119 case '-': negative = 1; // Fall through to increment position 120 case '+': p++; 121 } 122 123 number = 0.; 124 exponent = 0; 125 num_digits = 0; 126 num_decimals = 0; 127 128 // Process string of digits 129 while (isdigit(*p)) 130 { 131 number = number * 10. + (*p - '0'); 132 p++; 133 num_digits++; 134 } 135 136 // Process decimal part 137 if (*p == '.') 138 { 139 p++; 140 141 while (isdigit(*p)) 142 { 143 number = number * 10. + (*p - '0'); 144 p++; 145 num_digits++; 146 num_decimals++; 147 } 148 149 exponent -= num_decimals; 150 } 151 152 if (num_digits == 0) 153 { 154#ifdef ROCKBOX 155 rb_errno = 1; 156#else 157 errno = ERANGE; 158#endif 159 return 0.0; 160 } 161 162 // Correct for sign 163 if (negative) number = -number; 164 165 // Process an exponent string 166 if (*p == 'e' || *p == 'E') 167 { 168 // Handle optional sign 169 negative = 0; 170 switch(*++p) 171 { 172 case '-': negative = 1; // Fall through to increment pos 173 case '+': p++; 174 } 175 176 // Process string of digits 177 n = 0; 178 while (isdigit(*p)) 179 { 180 n = n * 10 + (*p - '0'); 181 p++; 182 } 183 184 if (negative) 185 exponent -= n; 186 else 187 exponent += n; 188 } 189 190#ifndef ROCKBOX 191 if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) 192 { 193 errno = ERANGE; 194 return HUGE_VAL; 195 } 196#endif 197 198 // Scale the result 199 p10 = 10.; 200 n = exponent; 201 if (n < 0) n = -n; 202 while (n) 203 { 204 if (n & 1) 205 { 206 if (exponent < 0) 207 number /= p10; 208 else 209 number *= p10; 210 } 211 n >>= 1; 212 p10 *= p10; 213 } 214 215#ifndef ROCKBOX 216 if (number == HUGE_VAL) errno = ERANGE; 217#endif 218 if (endptr) *endptr = p; 219 220 return number; 221} 222 223double rb_atof(const char *str) 224{ 225 return rb_strtod(str, NULL); 226} 227 228 229/* Implementation of ftoa(), original. */ 230void rb_ftoan(float f, char* out, int size) 231{ 232 #define SBUFSIZE 12 233 char sbuf[SBUFSIZE]; 234 235 /* Zero out string. */ 236 *out = '\0'; 237 size--; 238 239 /* Handle negative numbers. */ 240 if(f < 0.0) 241 { 242 f = -f; 243 strcat(out, "-"); 244 size--; 245 } 246 247 /* Find and convert integer part. */ 248 int int_part = (int) f; 249 snprintf(sbuf, SBUFSIZE, "%d", int_part); 250 int int_part_len = strlen(sbuf); 251 if(size < int_part_len) 252 return; 253 254 /* Append integral part to output string. */ 255 strcat(out, sbuf); 256 size -= int_part_len; 257 258 /* Check whether further content is possible. */ 259 if(size <= 0) 260 return; 261 262 /* Append decimal point. */ 263 strcat(out, "."); 264 size--; 265 266 /* Calculate first rest. */ 267 float rest1 = (f - (float) int_part) * 1000000000.0; 268 269 /* If there is no fractional part, return here. */ 270 if(rest1 == 0.0f) 271 return; 272 273 /* Convert the first rest to string. */ 274 int irest1 = (int) rest1; 275 snprintf(sbuf, SBUFSIZE, "%09d", irest1); 276 277 /* Append first rest to output string. */ 278 int rest1_len = strlen(sbuf); 279 int rest1_minlen = MIN(size, rest1_len); 280 strncat(out, sbuf, rest1_minlen); 281 size -= rest1_minlen; 282 283 /* Check whether output string still has enough space. */ 284 if(size <= 0) 285 return; 286 287 /* Calculate second rest. */ 288 float rest2 = (rest1 - (float) irest1) * 1000000000.0; 289 290 /* If no second rest, check whether 291 the output string has unwanted zero trail, 292 remove it and end processing here. */ 293 if(rest2 == 0.0f) 294 { 295 char* zerotrail = out + strlen(out) - 1; 296 297 for(; zerotrail >= out; zerotrail--) 298 { 299 if(*zerotrail == '0') 300 *zerotrail = '\0'; 301 else 302 return; 303 } 304 } 305 306 /* Convert second rest. */ 307 int irest2 = (int) rest2; 308 snprintf(sbuf, SBUFSIZE, "%09d", irest2); 309 310 /* Append second rest to the output string. */ 311 int rest2_len = strlen(sbuf); 312 int rest2_minlen = MIN(size, rest2_len); 313 strncat(out, sbuf, rest2_minlen); 314 315 /* Cut trailing zeroes. */ 316 char* zerotrail = out + strlen(out) - 1; 317 for(;zerotrail >= out; zerotrail--) 318 { 319 if(*zerotrail == '0') 320 *zerotrail = '\0'; 321 else 322 return; 323 } 324} 325 326 327/* Implementation of atol(), adapted from 328 the atoi() implementation in Rockbox. */ 329long rb_atol(const char* str) 330{ 331 long value = 0L; 332 long sign = 1L; 333 334 while (isspace(*str)) 335 { 336 str++; 337 } 338 339 if ('-' == *str) 340 { 341 sign = -1L; 342 str++; 343 } 344 else if ('+' == *str) 345 { 346 str++; 347 } 348 349 while ('0' == *str) 350 { 351 str++; 352 } 353 354 while (isdigit(*str)) 355 { 356 value = (value * 10L) + (*str - '0'); 357 str++; 358 } 359 360 return value * sign; 361} 362 363 364/* Implementation of sin() and cos(), 365 adapted from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/ 366*/ 367 368float rb_sin(float rad) 369{ 370 int cycles; 371 372 /* Trim input value to -PI..PI interval. */ 373 if(rad > 3.14159265) 374 { 375 cycles = rad / 6.28318531; 376 rad -= (6.28318531 * (float) cycles); 377 } 378 else if(rad < -3.14159265) 379 { 380 cycles = rad / -6.28318531; 381 rad += (6.28318531 * (float) cycles); 382 } 383 384 if(rad < 0) 385 return (1.27323954 * rad + 0.405284735 * rad * rad); 386 else 387 return (1.27323954 * rad - 0.405284735 * rad * rad); 388} 389 390float rb_cos(float rad) 391{ 392 /* Compute cosine: sin(x + PI/2) = cos(x) */ 393 return rb_sin(rad + 1.57079632); 394} 395 396 397/* Emulation of fscanf(fd, "%f", (float*) xxx); 398 Basically a reimplementation of rb_strtod() above. */ 399int rb_fscanf_f(int fd, float* f) 400{ 401 #define FSCANF_F_BUFSIZE 64 402 char buf[FSCANF_F_BUFSIZE]; 403 404 /* Read line from file. */ 405 int bytes_read = rb->read_line(fd, buf, FSCANF_F_BUFSIZE-1); 406 407 /* Terminate string. */ 408 if(bytes_read >= FSCANF_F_BUFSIZE) 409 buf[FSCANF_F_BUFSIZE-1] = '\0'; 410 else 411 buf[bytes_read-1] = '\0'; 412 413 /* Convert buffer to float. */ 414 *f = rb_atof(buf); 415 416 /* If there was an error, no float was read. */ 417 if(rb_errno) 418 return 0; 419 420 return 1; 421} 422 423/* Emulation of fprintf(fd, "%f\n", (float*) xxx); */ 424int rb_fprintf_f(int fd, float f) 425{ 426 #define FPRINTF_F_BUFSIZE 64 427 char buf[FPRINTF_F_BUFSIZE]; 428 const char* next_line = "\n"; 429 430 /* Convert float to string. */ 431 rb_ftoan(f, buf, sizeof(buf)-1); 432 433 /* Add next line character. */ 434 strcat(buf, next_line); 435 436 /* Write string into file. */ 437 return write(fd, buf, strlen(buf)); 438} 439 440 441/* Natural logarithm. 442 Taken from glibc-2.8 */ 443static const float 444ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ 445ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ 446two25 = 3.355443200e+07, /* 0x4c000000 */ 447Lg1 = 6.6666668653e-01, /* 3F2AAAAB */ 448Lg2 = 4.0000000596e-01, /* 3ECCCCCD */ 449Lg3 = 2.8571429849e-01, /* 3E924925 */ 450Lg4 = 2.2222198546e-01, /* 3E638E29 */ 451Lg5 = 1.8183572590e-01, /* 3E3A3325 */ 452Lg6 = 1.5313838422e-01, /* 3E1CD04F */ 453Lg7 = 1.4798198640e-01; /* 3E178897 */ 454 455static const float zero = 0.0; 456 457/* A union which permits us to convert between a float and a 32 bit 458 int. */ 459 460typedef union 461{ 462 float value; 463 uint32_t word; 464} ieee_float_shape_type; 465 466/* Get a 32 bit int from a float. */ 467 468#define GET_FLOAT_WORD(i,d) \ 469do { \ 470 ieee_float_shape_type gf_u; \ 471 gf_u.value = (d); \ 472 (i) = gf_u.word; \ 473} while (0) 474 475/* Set a float from a 32 bit int. */ 476 477#define SET_FLOAT_WORD(d,i) \ 478do { \ 479 ieee_float_shape_type sf_u; \ 480 sf_u.word = (i); \ 481 (d) = sf_u.value; \ 482} while (0) 483 484 485float rb_log(float x) 486{ 487 float hfsq, f, s, z, R, w, t1, t2, dk; 488 int32_t k, ix, i, j; 489 490 GET_FLOAT_WORD(ix,x); 491 492 k=0; 493 if (ix < 0x00800000) { /* x < 2**-126 */ 494 if ((ix&0x7fffffff)==0) 495 return -two25/(x-x); /* log(+-0)=-inf */ 496 if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ 497 k -= 25; x *= two25; /* subnormal number, scale up x */ 498 GET_FLOAT_WORD(ix,x); 499 } 500 if (ix >= 0x7f800000) return x+x; 501 k += (ix>>23)-127; 502 ix &= 0x007fffff; 503 i = (ix+(0x95f64<<3))&0x800000; 504 SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ 505 k += (i>>23); 506 f = x-(float)1.0; 507 if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ 508 if(f==zero) { 509 if(k==0) 510 return zero; 511 else 512 { 513 dk=(float)k; 514 return dk*ln2_hi+dk*ln2_lo; 515 } 516 } 517 R = f*f*((float)0.5-(float)0.33333333333333333*f); 518 if(k==0) 519 return f-R; 520 else 521 { 522 dk=(float)k; 523 return dk*ln2_hi-((R-dk*ln2_lo)-f); 524 } 525 } 526 s = f/((float)2.0+f); 527 dk = (float)k; 528 z = s*s; 529 i = ix-(0x6147a<<3); 530 w = z*z; 531 j = (0x6b851<<3)-ix; 532 t1= w*(Lg2+w*(Lg4+w*Lg6)); 533 t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); 534 i |= j; 535 R = t2+t1; 536 if(i>0) { 537 hfsq=(float)0.5*f*f; 538 if(k==0) 539 return f-(hfsq-s*(hfsq+R)); 540 else 541 return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); 542 } else { 543 if(k==0) 544 return f-s*(f-R); 545 else 546 return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); 547 } 548} 549 550 551/* Logarithm for 10th base, 552 taken from glibc-2.8 */ 553 554static const float 555ivln10 = 4.3429449201e-01, /* 0x3ede5bd9 */ 556log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */ 557log10_2lo = 7.9034151668e-07; /* 0x355427db */ 558 559float rb_log10(float x) 560{ 561 float y,z; 562 int32_t i,k,hx; 563 564 GET_FLOAT_WORD(hx,x); 565 566 k=0; 567 if (hx < 0x00800000) { /* x < 2**-126 */ 568 if ((hx&0x7fffffff)==0) 569 return -two25/(x-x); /* log(+-0)=-inf */ 570 if (hx<0) return (x-x)/(x-x); /* log(-#) = NaN */ 571 k -= 25; x *= two25; /* subnormal number, scale up x */ 572 GET_FLOAT_WORD(hx,x); 573 } 574 if (hx >= 0x7f800000) return x+x; 575 k += (hx>>23)-127; 576 i = ((uint32_t)k&0x80000000)>>31; 577 hx = (hx&0x007fffff)|((0x7f-i)<<23); 578 y = (float)(k+i); 579 SET_FLOAT_WORD(x,hx); 580 z = y*log10_2lo + ivln10*rb_log(x); 581 return z+y*log10_2hi; 582} 583 584 585/* Power function, taken from glibc-2.8 and dietlibc-0.32 */ 586static const float 587huge = 1.0e+30, 588tiny = 1.0e-30, 589one = 1.0f; 590 591float rb_pow(float x, float y) 592{ 593 unsigned int e; 594 float result; 595 596 /* Special cases 0^x */ 597 if(x == 0.0f) 598 { 599 if(y > 0.0f) 600 return 0.0f; 601 else if(y == 0.0f) 602 return 1.0f; 603 else 604 return 1.0f / x; 605 } 606 607 /* Special case x^n where n is integer */ 608 if(y == (int) (e = (int) y)) 609 { 610 if((int) e < 0) 611 { 612 e = -e; 613 x = 1.0f / x; 614 } 615 616 result = 1.0f; 617 618 while(1) 619 { 620 if(e & 1) 621 result *= x; 622 623 if((e >>= 1) == 0) 624 break; 625 626 x *= x; 627 } 628 629 return result; 630 } 631 632 /* Normal case */ 633 return rb_exp(rb_log(x) * y); 634} 635 636 637 638/* Square root function, original. */ 639float rb_sqrt(float x) 640{ 641 float z; 642 int32_t sign = (int)0x80000000; 643 int32_t ix,s,q,m,t,i; 644 uint32_t r; 645 646 GET_FLOAT_WORD(ix,x); 647 648 /* take care of Inf and NaN */ 649 if((ix&0x7f800000)==0x7f800000) { 650 return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf 651 sqrt(-inf)=sNaN */ 652 } 653 /* take care of zero */ 654 if(ix<=0) { 655 if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ 656 else if(ix<0) 657 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ 658 } 659 /* normalize x */ 660 m = (ix>>23); 661 if(m==0) { /* subnormal x */ 662 for(i=0;(ix&0x00800000)==0;i++) ix<<=1; 663 m -= i-1; 664 } 665 m -= 127; /* unbias exponent */ 666 ix = (ix&0x007fffff)|0x00800000; 667 if(m&1) /* odd m, double x to make it even */ 668 ix += ix; 669 m >>= 1; /* m = [m/2] */ 670 671 /* generate sqrt(x) bit by bit */ 672 ix += ix; 673 q = s = 0; /* q = sqrt(x) */ 674 r = 0x01000000; /* r = moving bit from right to left */ 675 676 while(r!=0) { 677 t = s+r; 678 if(t<=ix) { 679 s = t+r; 680 ix -= t; 681 q += r; 682 } 683 ix += ix; 684 r>>=1; 685 } 686 687 /* use floating add to find out rounding direction */ 688 if(ix!=0) { 689 z = one-tiny; /* trigger inexact flag */ 690 if (z>=one) { 691 z = one+tiny; 692 if (z>one) 693 q += 2; 694 else 695 q += (q&1); 696 } 697 } 698 ix = (q>>1)+0x3f000000; 699 ix += (m <<23); 700 SET_FLOAT_WORD(z,ix); 701 return z; 702} 703 704/* Absolute value, simple calculus */ 705float rb_fabs(float x) 706{ 707 return (x < 0.0f) ? -x : x; 708} 709 710/* Arc tangent, 711 taken from glibc-2.8. */ 712 713static const float atanhi[] = { 714 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ 715 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ 716 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ 717 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ 718}; 719 720static const float atanlo[] = { 721 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ 722 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ 723 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ 724 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ 725}; 726 727static const float aT[] = { 728 3.3333334327e-01, /* 0x3eaaaaaa */ 729 -2.0000000298e-01, /* 0xbe4ccccd */ 730 1.4285714924e-01, /* 0x3e124925 */ 731 -1.1111110449e-01, /* 0xbde38e38 */ 732 9.0908870101e-02, /* 0x3dba2e6e */ 733 -7.6918758452e-02, /* 0xbd9d8795 */ 734 6.6610731184e-02, /* 0x3d886b35 */ 735 -5.8335702866e-02, /* 0xbd6ef16b */ 736 4.9768779427e-02, /* 0x3d4bda59 */ 737 -3.6531571299e-02, /* 0xbd15a221 */ 738 1.6285819933e-02, /* 0x3c8569d7 */ 739}; 740 741 742float rb_atan(float x) 743{ 744 float w,s1,s2,z; 745 int32_t ix,hx,id; 746 747 GET_FLOAT_WORD(hx,x); 748 ix = hx&0x7fffffff; 749 if(ix>=0x50800000) { /* if |x| >= 2^34 */ 750 if(ix>0x7f800000) 751 return x+x; /* NaN */ 752 if(hx>0) return atanhi[3]+atanlo[3]; 753 else return -atanhi[3]-atanlo[3]; 754 } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ 755 if (ix < 0x31000000) { /* |x| < 2^-29 */ 756 if(huge+x>one) return x; /* raise inexact */ 757 } 758 id = -1; 759 } else { 760 x = rb_fabs(x); 761 if (ix < 0x3f980000) { /* |x| < 1.1875 */ 762 if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ 763 id = 0; x = ((float)2.0*x-one)/((float)2.0+x); 764 } else { /* 11/16<=|x|< 19/16 */ 765 id = 1; x = (x-one)/(x+one); 766 } 767 } else { 768 if (ix < 0x401c0000) { /* |x| < 2.4375 */ 769 id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); 770 } else { /* 2.4375 <= |x| < 2^66 */ 771 id = 3; x = -(float)1.0/x; 772 } 773 }} 774 /* end of argument reduction */ 775 z = x*x; 776 w = z*z; 777 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ 778 s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); 779 s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); 780 if (id<0) return x - x*(s1+s2); 781 else { 782 z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); 783 return (hx<0)? -z:z; 784 } 785} 786 787/* Arc tangent from two variables, original. */ 788 789static const float 790pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */ 791pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */ 792pi = 3.1415927410e+00, /* 0x40490fdb */ 793pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */ 794 795float rb_atan2(float x, float y) 796{ 797 float z; 798 int32_t k,m,hx,hy,ix,iy; 799 800 GET_FLOAT_WORD(hx,x); 801 ix = hx&0x7fffffff; 802 GET_FLOAT_WORD(hy,y); 803 iy = hy&0x7fffffff; 804 if((ix>0x7f800000)|| 805 (iy>0x7f800000)) /* x or y is NaN */ 806 return x+y; 807 if(hx==0x3f800000) return rb_atan(y); /* x=1.0 */ 808 m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ 809 810 /* when y = 0 */ 811 if(iy==0) { 812 switch(m) { 813 case 0: 814 case 1: return y; /* atan(+-0,+anything)=+-0 */ 815 case 2: return pi+tiny;/* atan(+0,-anything) = pi */ 816 case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ 817 } 818 } 819 /* when x = 0 */ 820 if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; 821 822 /* when x is INF */ 823 if(ix==0x7f800000) { 824 if(iy==0x7f800000) { 825 switch(m) { 826 case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ 827 case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ 828 case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ 829 case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ 830 } 831 } else { 832 switch(m) { 833 case 0: return zero ; /* atan(+...,+INF) */ 834 case 1: return -zero ; /* atan(-...,+INF) */ 835 case 2: return pi+tiny ; /* atan(+...,-INF) */ 836 case 3: return -pi-tiny ; /* atan(-...,-INF) */ 837 } 838 } 839 } 840 /* when y is INF */ 841 if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; 842 843 /* compute y/x */ 844 k = (iy-ix)>>23; 845 if(k > 60) z=pi_o_2+(float)0.5*pi_lo; /* |y/x| > 2**60 */ 846 else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ 847 else z=rb_atan(rb_fabs(y/x)); /* safe to do y/x */ 848 switch (m) { 849 case 0: return z ; /* atan(+,+) */ 850 case 1: { 851 uint32_t zh; 852 GET_FLOAT_WORD(zh,z); 853 SET_FLOAT_WORD(z,zh ^ 0x80000000); 854 } 855 return z ; /* atan(-,+) */ 856 case 2: return pi-(z-pi_lo);/* atan(+,-) */ 857 default: /* case 3 */ 858 return (z-pi_lo)-pi;/* atan(-,-) */ 859 } 860} 861 862 863/* Sine hyperbolic, taken from dietlibc-0.32 */ 864float rb_sinh(float x) 865{ 866 float y = rb_exp(x); 867 return (y - 1.0f / y) * 0.5f; 868} 869 870 871/* Tangent, simple calculus solution. */ 872float rb_tan(float x) 873{ 874 return rb_sin(x) / rb_cos(x); 875} 876 877 878 879/* Exponential function, 880 taken from glibc-2.8 881 As it uses double values and udefines some symbols, 882 it was moved to the end of the source code */ 883 884#define W52 (2.22044605e-16) 885#define W55 (2.77555756e-17) 886#define W58 (3.46944695e-18) 887#define W59 (1.73472348e-18) 888#define W60 (8.67361738e-19) 889const float __exp_deltatable[178] = { 890 0*W60, 16558714*W60, -10672149*W59, 1441652*W60, 891 -15787963*W55, 462888*W60, 7291806*W60, 1698880*W60, 892 -14375103*W58, -2021016*W60, 728829*W60, -3759654*W60, 893 3202123*W60, -10916019*W58, -251570*W60, -1043086*W60, 894 8207536*W60, -409964*W60, -5993931*W60, -475500*W60, 895 2237522*W60, 324170*W60, -244117*W60, 32077*W60, 896 123907*W60, -1019734*W60, -143*W60, 813077*W60, 897 743345*W60, 462461*W60, 629794*W60, 2125066*W60, 898 -2339121*W60, -337951*W60, 9922067*W60, -648704*W60, 899 149407*W60, -2687209*W60, -631608*W60, 2128280*W60, 900 -4882082*W60, 2001360*W60, 175074*W60, 2923216*W60, 901 -538947*W60, -1212193*W60, -1920926*W60, -1080577*W60, 902 3690196*W60, 2643367*W60, 2911937*W60, 671455*W60, 903 -1128674*W60, 593282*W60, -5219347*W60, -1941490*W60, 904 11007953*W60, 239609*W60, -2969658*W60, -1183650*W60, 905 942998*W60, 699063*W60, 450569*W60, -329250*W60, 906 -7257875*W60, -312436*W60, 51626*W60, 555877*W60, 907 -641761*W60, 1565666*W60, 884327*W60, -10960035*W60, 908 -2004679*W60, -995793*W60, -2229051*W60, -146179*W60, 909 -510327*W60, 1453482*W60, -3778852*W60, -2238056*W60, 910 -4895983*W60, 3398883*W60, -252738*W60, 1230155*W60, 911 346918*W60, 1109352*W60, 268941*W60, -2930483*W60, 912 -1036263*W60, -1159280*W60, 1328176*W60, 2937642*W60, 913 -9371420*W60, -6902650*W60, -1419134*W60, 1442904*W60, 914 -1319056*W60, -16369*W60, 696555*W60, -279987*W60, 915 -7919763*W60, 252741*W60, 459711*W60, -1709645*W60, 916 354913*W60, 6025867*W60, -421460*W60, -853103*W60, 917 -338649*W60, 962151*W60, 955965*W60, 784419*W60, 918 -3633653*W60, 2277133*W60, -8847927*W52, 1223028*W60, 919 5907079*W60, 623167*W60, 5142888*W60, 2599099*W60, 920 1214280*W60, 4870359*W60, 593349*W60, -57705*W60, 921 7761209*W60, -5564097*W60, 2051261*W60, 6216869*W60, 922 4692163*W60, 601691*W60, -5264906*W60, 1077872*W60, 923 -3205949*W60, 1833082*W60, 2081746*W60, -987363*W60, 924 -1049535*W60, 2015244*W60, 874230*W60, 2168259*W60, 925 -1740124*W60, -10068269*W60, -18242*W60, -3013583*W60, 926 580601*W60, -2547161*W60, -535689*W60, 2220815*W60, 927 1285067*W60, 2806933*W60, -983086*W60, -1729097*W60, 928 -1162985*W60, -2561904*W60, 801988*W60, 244351*W60, 929 1441893*W60, -7517981*W60, 271781*W60, -15021588*W60, 930 -2341588*W60, -919198*W60, 1642232*W60, 4771771*W60, 931 -1220099*W60, -3062372*W60, 628624*W60, 1278114*W60, 932 13083513*W60, -10521925*W60, 3180310*W60, -1659307*W60, 933 3543773*W60, 2501203*W60, 4151*W60, -340748*W60, 934 -2285625*W60, 2495202*W60 935}; 936 937const double __exp_atable[355] /* __attribute__((mode(DF))) */ = { 938 0.707722561055888932371, /* 0x0.b52d4e46605c27ffd */ 939 0.709106182438804188967, /* 0x0.b587fb96f75097ffb */ 940 0.710492508843861281234, /* 0x0.b5e2d649899167ffd */ 941 0.711881545564593931623, /* 0x0.b63dde74d36bdfffe */ 942 0.713273297897442870573, /* 0x0.b699142f945f87ffc */ 943 0.714667771153751463236, /* 0x0.b6f477909c4ea0001 */ 944 0.716064970655995725059, /* 0x0.b75008aec758f8004 */ 945 0.717464901723956938193, /* 0x0.b7abc7a0eea7e0002 */ 946 0.718867569715736398602, /* 0x0.b807b47e1586c7ff8 */ 947 0.720272979947266023271, /* 0x0.b863cf5d10e380003 */ 948 0.721681137825144314297, /* 0x0.b8c01855195c37ffb */ 949 0.723092048691992950199, /* 0x0.b91c8f7d213740004 */ 950 0.724505717938892290800, /* 0x0.b97934ec5002d0007 */ 951 0.725922150953176470431, /* 0x0.b9d608b9c92ea7ffc */ 952 0.727341353138962865022, /* 0x0.ba330afcc29e98003 */ 953 0.728763329918453162104, /* 0x0.ba903bcc8618b7ffc */ 954 0.730188086709957051568, /* 0x0.baed9b40591ba0000 */ 955 0.731615628948127705309, /* 0x0.bb4b296f931e30002 */ 956 0.733045962086486091436, /* 0x0.bba8e671a05617ff9 */ 957 0.734479091556371366251, /* 0x0.bc06d25dd49568001 */ 958 0.735915022857225542529, /* 0x0.bc64ed4bce8f6fff9 */ 959 0.737353761441304711410, /* 0x0.bcc33752f915d7ff9 */ 960 0.738795312814142124419, /* 0x0.bd21b08af98e78005 */ 961 0.740239682467211168593, /* 0x0.bd80590b65e9a8000 */ 962 0.741686875913991849885, /* 0x0.bddf30ebec4a10000 */ 963 0.743136898669507939299, /* 0x0.be3e38443c84e0007 */ 964 0.744589756269486091620, /* 0x0.be9d6f2c1d32a0002 */ 965 0.746045454254026796384, /* 0x0.befcd5bb59baf8004 */ 966 0.747503998175051087583, /* 0x0.bf5c6c09ca84c0003 */ 967 0.748965393601880857739, /* 0x0.bfbc322f5b18b7ff8 */ 968 0.750429646104262104698, /* 0x0.c01c2843f776fffff */ 969 0.751896761271877989160, /* 0x0.c07c4e5fa18b88002 */ 970 0.753366744698445112140, /* 0x0.c0dca49a5fb18fffd */ 971 0.754839601988627206827, /* 0x0.c13d2b0c444db0005 */ 972 0.756315338768691947122, /* 0x0.c19de1cd798578006 */ 973 0.757793960659406629066, /* 0x0.c1fec8f623723fffd */ 974 0.759275473314173443536, /* 0x0.c25fe09e8a0f47ff8 */ 975 0.760759882363831851927, /* 0x0.c2c128dedc88f8000 */ 976 0.762247193485956486805, /* 0x0.c322a1cf7d6e7fffa */ 977 0.763737412354726363781, /* 0x0.c3844b88cb9347ffc */ 978 0.765230544649828092739, /* 0x0.c3e626232bd8f7ffc */ 979 0.766726596071518051729, /* 0x0.c44831b719bf18002 */ 980 0.768225572321911687194, /* 0x0.c4aa6e5d12d078001 */ 981 0.769727479119219348810, /* 0x0.c50cdc2da64a37ffb */ 982 0.771232322196981678892, /* 0x0.c56f7b41744490001 */ 983 0.772740107296721268087, /* 0x0.c5d24bb1259e70004 */ 984 0.774250840160724651565, /* 0x0.c6354d95640dd0007 */ 985 0.775764526565368872643, /* 0x0.c6988106fec447fff */ 986 0.777281172269557396602, /* 0x0.c6fbe61eb1bd0ffff */ 987 0.778800783068235302750, /* 0x0.c75f7cf560942fffc */ 988 0.780323364758801041312, /* 0x0.c7c345a3f1983fffe */ 989 0.781848923151573727006, /* 0x0.c8274043594cb0002 */ 990 0.783377464064598849602, /* 0x0.c88b6cec94b3b7ff9 */ 991 0.784908993312207869935, /* 0x0.c8efcbb89cba27ffe */ 992 0.786443516765346961618, /* 0x0.c9545cc0a88c70003 */ 993 0.787981040257604625744, /* 0x0.c9b9201dc643bfffa */ 994 0.789521569657452682047, /* 0x0.ca1e15e92a5410007 */ 995 0.791065110849462849192, /* 0x0.ca833e3c1ae510005 */ 996 0.792611669712891875319, /* 0x0.cae8992fd84667ffd */ 997 0.794161252150049179450, /* 0x0.cb4e26ddbc207fff8 */ 998 0.795713864077794763584, /* 0x0.cbb3e75f301b60003 */ 999 0.797269511407239561694, /* 0x0.cc19dacd978cd8002 */ 1000 0.798828200086368567220, /* 0x0.cc8001427e55d7ffb */ 1001 0.800389937624300440456, /* 0x0.cce65ade24d360006 */ 1002 0.801954725261124767840, /* 0x0.cd4ce7a5de839fffb */ 1003 0.803522573691593189330, /* 0x0.cdb3a7c79a678fffd */ 1004 0.805093487311204114563, /* 0x0.ce1a9b563965ffffc */ 1005 0.806667472122675088819, /* 0x0.ce81c26b838db8000 */ 1006 0.808244534127439906441, /* 0x0.cee91d213f8428002 */ 1007 0.809824679342317166307, /* 0x0.cf50ab9144d92fff9 */ 1008 0.811407913793616542005, /* 0x0.cfb86dd5758c2ffff */ 1009 0.812994243520784198882, /* 0x0.d0206407c20e20005 */ 1010 0.814583674571603966162, /* 0x0.d0888e4223facfff9 */ 1011 0.816176213022088536960, /* 0x0.d0f0ec9eb3f7c8002 */ 1012 0.817771864936188586101, /* 0x0.d1597f377d6768002 */ 1013 0.819370636400374108252, /* 0x0.d1c24626a46eafff8 */ 1014 0.820972533518165570298, /* 0x0.d22b41865ff1e7ff9 */ 1015 0.822577562404315121269, /* 0x0.d2947170f32ec7ff9 */ 1016 0.824185729164559344159, /* 0x0.d2fdd60097795fff8 */ 1017 0.825797039949601741075, /* 0x0.d3676f4fb796d0001 */ 1018 0.827411500902565544264, /* 0x0.d3d13d78b5f68fffb */ 1019 0.829029118181348834154, /* 0x0.d43b40960546d8001 */ 1020 0.830649897953322891022, /* 0x0.d4a578c222a058000 */ 1021 0.832273846408250750368, /* 0x0.d50fe617a3ba78005 */ 1022 0.833900969738858188772, /* 0x0.d57a88b1218e90002 */ 1023 0.835531274148056613016, /* 0x0.d5e560a94048f8006 */ 1024 0.837164765846411529371, /* 0x0.d6506e1aac8078003 */ 1025 0.838801451086016225394, /* 0x0.d6bbb1204074e0001 */ 1026 0.840441336100884561780, /* 0x0.d72729d4c28518004 */ 1027 0.842084427144139224814, /* 0x0.d792d8530e12b0001 */ 1028 0.843730730487052604790, /* 0x0.d7febcb61273e7fff */ 1029 0.845380252404570153833, /* 0x0.d86ad718c308dfff9 */ 1030 0.847032999194574087728, /* 0x0.d8d727962c69d7fff */ 1031 0.848688977161248581090, /* 0x0.d943ae49621ce7ffb */ 1032 0.850348192619261200615, /* 0x0.d9b06b4d832ef8005 */ 1033 0.852010651900976245816, /* 0x0.da1d5ebdc22220005 */ 1034 0.853676361342631029337, /* 0x0.da8a88b555baa0006 */ 1035 0.855345327311054837175, /* 0x0.daf7e94f965f98004 */ 1036 0.857017556155879489641, /* 0x0.db6580a7c98f7fff8 */ 1037 0.858693054267390953857, /* 0x0.dbd34ed9617befff8 */ 1038 0.860371828028939855647, /* 0x0.dc4153ffc8b65fff9 */ 1039 0.862053883854957292436, /* 0x0.dcaf90368bfca8004 */ 1040 0.863739228154875360306, /* 0x0.dd1e0399328d87ffe */ 1041 0.865427867361348468455, /* 0x0.dd8cae435d303fff9 */ 1042 0.867119807911702289458, /* 0x0.ddfb9050b1cee8006 */ 1043 0.868815056264353846599, /* 0x0.de6aa9dced8448001 */ 1044 0.870513618890481399881, /* 0x0.ded9fb03db7320006 */ 1045 0.872215502247877139094, /* 0x0.df4983e1380657ff8 */ 1046 0.873920712852848668986, /* 0x0.dfb94490ffff77ffd */ 1047 0.875629257204025623884, /* 0x0.e0293d2f1cb01fff9 */ 1048 0.877341141814212965880, /* 0x0.e0996dd786fff0007 */ 1049 0.879056373217612985183, /* 0x0.e109d6a64f5d57ffc */ 1050 0.880774957955916648615, /* 0x0.e17a77b78e72a7ffe */ 1051 0.882496902590150900078, /* 0x0.e1eb5127722cc7ff8 */ 1052 0.884222213673356738383, /* 0x0.e25c63121fb0c8006 */ 1053 0.885950897802399772740, /* 0x0.e2cdad93ec5340003 */ 1054 0.887682961567391237685, /* 0x0.e33f30c925fb97ffb */ 1055 0.889418411575228162725, /* 0x0.e3b0ecce2d05ffff9 */ 1056 0.891157254447957902797, /* 0x0.e422e1bf727718006 */ 1057 0.892899496816652704641, /* 0x0.e4950fb9713fc7ffe */ 1058 0.894645145323828439008, /* 0x0.e50776d8b0e60fff8 */ 1059 0.896394206626591749641, /* 0x0.e57a1739c8fadfffc */ 1060 0.898146687421414902124, /* 0x0.e5ecf0f97c5798007 */ 1061 0.899902594367530173098, /* 0x0.e660043464e378005 */ 1062 0.901661934163603406867, /* 0x0.e6d3510747e150006 */ 1063 0.903424713533971135418, /* 0x0.e746d78f06cd97ffd */ 1064 0.905190939194458810123, /* 0x0.e7ba97e879c91fffc */ 1065 0.906960617885092856864, /* 0x0.e82e92309390b0007 */ 1066 0.908733756358986566306, /* 0x0.e8a2c6845544afffa */ 1067 0.910510361377119825629, /* 0x0.e9173500c8abc7ff8 */ 1068 0.912290439722343249336, /* 0x0.e98bddc30f98b0002 */ 1069 0.914073998177417412765, /* 0x0.ea00c0e84bc4c7fff */ 1070 0.915861043547953501680, /* 0x0.ea75de8db8094fffe */ 1071 0.917651582652244779397, /* 0x0.eaeb36d09d3137ffe */ 1072 0.919445622318405764159, /* 0x0.eb60c9ce4ed3dffff */ 1073 0.921243169397334638073, /* 0x0.ebd697a43995b0007 */ 1074 0.923044230737526172328, /* 0x0.ec4ca06fc7768fffa */ 1075 0.924848813220121135342, /* 0x0.ecc2e44e865b6fffb */ 1076 0.926656923710931002014, /* 0x0.ed39635df34e70006 */ 1077 0.928468569126343790092, /* 0x0.edb01dbbc2f5b7ffa */ 1078 0.930283756368834757725, /* 0x0.ee2713859aab57ffa */ 1079 0.932102492359406786818, /* 0x0.ee9e44d9342870004 */ 1080 0.933924784042873379360, /* 0x0.ef15b1d4635438005 */ 1081 0.935750638358567643520, /* 0x0.ef8d5a94f60f50007 */ 1082 0.937580062297704630580, /* 0x0.f0053f38f345cffff */ 1083 0.939413062815381727516, /* 0x0.f07d5fde3a2d98001 */ 1084 0.941249646905368053689, /* 0x0.f0f5bca2d481a8004 */ 1085 0.943089821583810716806, /* 0x0.f16e55a4e497d7ffe */ 1086 0.944933593864477061592, /* 0x0.f1e72b028a2827ffb */ 1087 0.946780970781518460559, /* 0x0.f2603cd9fb5430001 */ 1088 0.948631959382661205081, /* 0x0.f2d98b497d2a87ff9 */ 1089 0.950486566729423554277, /* 0x0.f353166f63e3dffff */ 1090 0.952344799896018723290, /* 0x0.f3ccde6a11ae37ffe */ 1091 0.954206665969085765512, /* 0x0.f446e357f66120000 */ 1092 0.956072172053890279009, /* 0x0.f4c12557964f0fff9 */ 1093 0.957941325265908139014, /* 0x0.f53ba48781046fffb */ 1094 0.959814132734539637840, /* 0x0.f5b66106555d07ffa */ 1095 0.961690601603558903308, /* 0x0.f6315af2c2027fffc */ 1096 0.963570739036113010927, /* 0x0.f6ac926b8aeb80004 */ 1097 0.965454552202857141381, /* 0x0.f728078f7c5008002 */ 1098 0.967342048278315158608, /* 0x0.f7a3ba7d66a908001 */ 1099 0.969233234469444204768, /* 0x0.f81fab543e1897ffb */ 1100 0.971128118008140250896, /* 0x0.f89bda33122c78007 */ 1101 0.973026706099345495256, /* 0x0.f9184738d4cf97ff8 */ 1102 0.974929006031422851235, /* 0x0.f994f284d3a5c0008 */ 1103 0.976835024947348973265, /* 0x0.fa11dc35bc7820002 */ 1104 0.978744770239899142285, /* 0x0.fa8f046b4fb7f8007 */ 1105 0.980658249138918636210, /* 0x0.fb0c6b449ab1cfff9 */ 1106 0.982575468959622777535, /* 0x0.fb8a10e1088fb7ffa */ 1107 0.984496437054508843888, /* 0x0.fc07f5602d79afffc */ 1108 0.986421160608523028820, /* 0x0.fc8618e0e55e47ffb */ 1109 0.988349647107594098099, /* 0x0.fd047b83571b1fffa */ 1110 0.990281903873210800357, /* 0x0.fd831d66f4c018002 */ 1111 0.992217938695037382475, /* 0x0.fe01fead3320bfff8 */ 1112 0.994157757657894713987, /* 0x0.fe811f703491e8006 */ 1113 0.996101369488558541238, /* 0x0.ff007fd5744490005 */ 1114 0.998048781093141101932, /* 0x0.ff801ffa9b9280007 */ 1115 1.000000000000000000000, /* 0x1.00000000000000000 */ 1116 1.001955033605393285965, /* 0x1.0080200565d29ffff */ 1117 1.003913889319761887310, /* 0x1.0100802aa0e80fff0 */ 1118 1.005876574715736104818, /* 0x1.01812090377240007 */ 1119 1.007843096764807100351, /* 0x1.020201541aad7fff6 */ 1120 1.009813464316352327214, /* 0x1.0283229c4c9820007 */ 1121 1.011787683565730677817, /* 0x1.030484836910a000e */ 1122 1.013765762469146736174, /* 0x1.0386272b9c077fffe */ 1123 1.015747708536026694351, /* 0x1.04080ab526304fff0 */ 1124 1.017733529475172815584, /* 0x1.048a2f412375ffff0 */ 1125 1.019723232714418781378, /* 0x1.050c94ef7ad5e000a */ 1126 1.021716825883923762690, /* 0x1.058f3be0f1c2d0004 */ 1127 1.023714316605201180057, /* 0x1.06122436442e2000e */ 1128 1.025715712440059545995, /* 0x1.06954e0fec63afff2 */ 1129 1.027721021151397406936, /* 0x1.0718b98f41c92fff6 */ 1130 1.029730250269221158939, /* 0x1.079c66d49bb2ffff1 */ 1131 1.031743407506447551857, /* 0x1.082056011a9230009 */ 1132 1.033760500517691527387, /* 0x1.08a487359ebd50002 */ 1133 1.035781537016238873464, /* 0x1.0928fa93490d4fff3 */ 1134 1.037806524719013578963, /* 0x1.09adb03b3e5b3000d */ 1135 1.039835471338248051878, /* 0x1.0a32a84e9e5760004 */ 1136 1.041868384612101516848, /* 0x1.0ab7e2eea5340ffff */ 1137 1.043905272300907460835, /* 0x1.0b3d603ca784f0009 */ 1138 1.045946142174331239262, /* 0x1.0bc3205a042060000 */ 1139 1.047991002016745332165, /* 0x1.0c4923682a086fffe */ 1140 1.050039859627715177527, /* 0x1.0ccf698898f3a000d */ 1141 1.052092722826109660856, /* 0x1.0d55f2dce5d1dfffb */ 1142 1.054149599440827866881, /* 0x1.0ddcbf86b09a5fff6 */ 1143 1.056210497317612961855, /* 0x1.0e63cfa7abc97fffd */ 1144 1.058275424318780855142, /* 0x1.0eeb23619c146fffb */ 1145 1.060344388322010722446, /* 0x1.0f72bad65714bffff */ 1146 1.062417397220589476718, /* 0x1.0ffa9627c38d30004 */ 1147 1.064494458915699715017, /* 0x1.1082b577d0eef0003 */ 1148 1.066575581342167566880, /* 0x1.110b18e893a90000a */ 1149 1.068660772440545025953, /* 0x1.1193c09c267610006 */ 1150 1.070750040138235936705, /* 0x1.121cacb4959befff6 */ 1151 1.072843392435016474095, /* 0x1.12a5dd543cf36ffff */ 1152 1.074940837302467588937, /* 0x1.132f529d59552000b */ 1153 1.077042382749654914030, /* 0x1.13b90cb250d08fff5 */ 1154 1.079148036789447484528, /* 0x1.14430bb58da3dfff9 */ 1155 1.081257807444460983297, /* 0x1.14cd4fc984c4a000e */ 1156 1.083371702785017154417, /* 0x1.1557d910df9c7000e */ 1157 1.085489730853784307038, /* 0x1.15e2a7ae292d30002 */ 1158 1.087611899742884524772, /* 0x1.166dbbc422d8c0004 */ 1159 1.089738217537583819804, /* 0x1.16f9157586772ffff */ 1160 1.091868692357631731528, /* 0x1.1784b4e533cacfff0 */ 1161 1.094003332327482702577, /* 0x1.18109a360fc23fff2 */ 1162 1.096142145591650907149, /* 0x1.189cc58b155a70008 */ 1163 1.098285140311341168136, /* 0x1.1929370751ea50002 */ 1164 1.100432324652149906842, /* 0x1.19b5eecdd79cefff0 */ 1165 1.102583706811727015711, /* 0x1.1a42ed01dbdba000e */ 1166 1.104739294993289488947, /* 0x1.1ad031c69a2eafff0 */ 1167 1.106899097422573863281, /* 0x1.1b5dbd3f66e120003 */ 1168 1.109063122341542140286, /* 0x1.1beb8f8fa8150000b */ 1169 1.111231377994659874592, /* 0x1.1c79a8dac6ad0fff4 */ 1170 1.113403872669181282605, /* 0x1.1d0809445a97ffffc */ 1171 1.115580614653132185460, /* 0x1.1d96b0effc9db000e */ 1172 1.117761612217810673898, /* 0x1.1e25a001332190000 */ 1173 1.119946873713312474002, /* 0x1.1eb4d69bdb2a9fff1 */ 1174 1.122136407473298902480, /* 0x1.1f4454e3bfae00006 */ 1175 1.124330221845670330058, /* 0x1.1fd41afcbb48bfff8 */ 1176 1.126528325196519908506, /* 0x1.2064290abc98c0001 */ 1177 1.128730725913251964394, /* 0x1.20f47f31c9aa7000f */ 1178 1.130937432396844410880, /* 0x1.21851d95f776dfff0 */ 1179 1.133148453059692917203, /* 0x1.2216045b6784efffa */ 1180 1.135363796355857157764, /* 0x1.22a733a6692ae0004 */ 1181 1.137583470716100553249, /* 0x1.2338ab9b3221a0004 */ 1182 1.139807484614418608939, /* 0x1.23ca6c5e27aadfff7 */ 1183 1.142035846532929888057, /* 0x1.245c7613b7f6c0004 */ 1184 1.144268564977221958089, /* 0x1.24eec8e06b035000c */ 1185 1.146505648458203463465, /* 0x1.258164e8cea85fff8 */ 1186 1.148747105501412235671, /* 0x1.26144a5180d380009 */ 1187 1.150992944689175123667, /* 0x1.26a7793f5de2efffa */ 1188 1.153243174560058870217, /* 0x1.273af1d712179000d */ 1189 1.155497803703682491111, /* 0x1.27ceb43d81d42fff1 */ 1190 1.157756840726344771440, /* 0x1.2862c097a3d29000c */ 1191 1.160020294239811677834, /* 0x1.28f7170a74cf4fff1 */ 1192 1.162288172883275239058, /* 0x1.298bb7bb0faed0004 */ 1193 1.164560485298402170388, /* 0x1.2a20a2ce920dffff4 */ 1194 1.166837240167474476460, /* 0x1.2ab5d86a4631ffff6 */ 1195 1.169118446164539637555, /* 0x1.2b4b58b36d5220009 */ 1196 1.171404112007080167155, /* 0x1.2be123cf786790002 */ 1197 1.173694246390975415341, /* 0x1.2c7739e3c0aac000d */ 1198 1.175988858069749065617, /* 0x1.2d0d9b15deb58fff6 */ 1199 1.178287955789017793514, /* 0x1.2da4478b627040002 */ 1200 1.180591548323240091978, /* 0x1.2e3b3f69fb794fffc */ 1201 1.182899644456603782686, /* 0x1.2ed282d76421d0004 */ 1202 1.185212252993012693694, /* 0x1.2f6a11f96c685fff3 */ 1203 1.187529382762033236513, /* 0x1.3001ecf60082ffffa */ 1204 1.189851042595508889847, /* 0x1.309a13f30f28a0004 */ 1205 1.192177241354644978669, /* 0x1.31328716a758cfff7 */ 1206 1.194507987909589896687, /* 0x1.31cb4686e1e85fffb */ 1207 1.196843291137896336843, /* 0x1.32645269dfd04000a */ 1208 1.199183159977805113226, /* 0x1.32fdaae604c39000f */ 1209 1.201527603343041317132, /* 0x1.339750219980dfff3 */ 1210 1.203876630171082595692, /* 0x1.3431424300e480007 */ 1211 1.206230249419600664189, /* 0x1.34cb8170b3fee000e */ 1212 1.208588470077065268869, /* 0x1.35660dd14dbd4fffc */ 1213 1.210951301134513435915, /* 0x1.3600e78b6bdfc0005 */ 1214 1.213318751604272271958, /* 0x1.369c0ec5c38ebfff2 */ 1215 1.215690830512196507537, /* 0x1.373783a718d29000f */ 1216 1.218067546930756250870, /* 0x1.37d3465662f480007 */ 1217 1.220448909901335365929, /* 0x1.386f56fa770fe0008 */ 1218 1.222834928513994334780, /* 0x1.390bb5ba5fc540004 */ 1219 1.225225611877684750397, /* 0x1.39a862bd3c7a8fff3 */ 1220 1.227620969111500981433, /* 0x1.3a455e2a37bcafffd */ 1221 1.230021009336254911271, /* 0x1.3ae2a8287dfbefff6 */ 1222 1.232425741726685064472, /* 0x1.3b8040df76f39fffa */ 1223 1.234835175450728295084, /* 0x1.3c1e287682e48fff1 */ 1224 1.237249319699482263931, /* 0x1.3cbc5f151b86bfff8 */ 1225 1.239668183679933477545, /* 0x1.3d5ae4e2cc0a8000f */ 1226 1.242091776620540377629, /* 0x1.3df9ba07373bf0006 */ 1227 1.244520107762172811399, /* 0x1.3e98deaa0d8cafffe */ 1228 1.246953186383919165383, /* 0x1.3f3852f32973efff0 */ 1229 1.249391019292643401078, /* 0x1.3fd816ffc72b90001 */ 1230 1.251833623164381181797, /* 0x1.40782b17863250005 */ 1231 1.254280999953110153911, /* 0x1.41188f42caf400000 */ 1232 1.256733161434815393410, /* 0x1.41b943b42945bfffd */ 1233 1.259190116985283935980, /* 0x1.425a4893e5f10000a */ 1234 1.261651875958665236542, /* 0x1.42fb9e0a2df4c0009 */ 1235 1.264118447754797758244, /* 0x1.439d443f608c4fff9 */ 1236 1.266589841787181258708, /* 0x1.443f3b5bebf850008 */ 1237 1.269066067469190262045, /* 0x1.44e183883e561fff7 */ 1238 1.271547134259576328224, /* 0x1.45841cecf7a7a0001 */ 1239 1.274033051628237434048, /* 0x1.462707b2c43020009 */ 1240 1.276523829025464573684, /* 0x1.46ca44023aa410007 */ 1241 1.279019475999373156531, /* 0x1.476dd2045d46ffff0 */ 1242 1.281520002043128991825, /* 0x1.4811b1e1f1f19000b */ 1243 1.284025416692967214122, /* 0x1.48b5e3c3edd74fff4 */ 1244 1.286535729509738823464, /* 0x1.495a67d3613c8fff7 */ 1245 1.289050950070396384145, /* 0x1.49ff3e396e19d000b */ 1246 1.291571087985403654081, /* 0x1.4aa4671f5b401fff1 */ 1247 1.294096152842774794011, /* 0x1.4b49e2ae56d19000d */ 1248 1.296626154297237043484, /* 0x1.4befb10fd84a3fff4 */ 1249 1.299161101984141142272, /* 0x1.4c95d26d41d84fff8 */ 1250 1.301701005575179204100, /* 0x1.4d3c46f01d9f0fff3 */ 1251 1.304245874766450485904, /* 0x1.4de30ec21097d0003 */ 1252 1.306795719266019562007, /* 0x1.4e8a2a0ccce3d0002 */ 1253 1.309350548792467483458, /* 0x1.4f3198fa10346fff5 */ 1254 1.311910373099227200545, /* 0x1.4fd95bb3be8cffffd */ 1255 1.314475201942565174546, /* 0x1.50817263bf0e5fffb */ 1256 1.317045045107389400535, /* 0x1.5129dd3418575000e */ 1257 1.319619912422941299109, /* 0x1.51d29c4f01c54ffff */ 1258 1.322199813675649204855, /* 0x1.527bafde83a310009 */ 1259 1.324784758729532718739, /* 0x1.5325180cfb8b3fffd */ 1260 1.327374757430096474625, /* 0x1.53ced504b2bd0fff4 */ 1261 1.329969819671041886272, /* 0x1.5478e6f02775e0001 */ 1262 1.332569955346704748651, /* 0x1.55234df9d8a59fff8 */ 1263 1.335175174370685002822, /* 0x1.55ce0a4c5a6a9fff6 */ 1264 1.337785486688218616860, /* 0x1.56791c1263abefff7 */ 1265 1.340400902247843806217, /* 0x1.57248376aef21fffa */ 1266 1.343021431036279800211, /* 0x1.57d040a420c0bfff3 */ 1267 1.345647083048053138662, /* 0x1.587c53c5a630f0002 */ 1268 1.348277868295411074918, /* 0x1.5928bd063fd7bfff9 */ 1269 1.350913796821875845231, /* 0x1.59d57c9110ad60006 */ 1270 1.353554878672557082439, /* 0x1.5a8292913d68cfffc */ 1271 1.356201123929036356254, /* 0x1.5b2fff3212db00007 */ 1272 1.358852542671913132777, /* 0x1.5bddc29edcc06fff3 */ 1273 1.361509145047255398051, /* 0x1.5c8bdd032ed16000f */ 1274 1.364170941142184734180, /* 0x1.5d3a4e8a5bf61fff4 */ 1275 1.366837941171020309735, /* 0x1.5de9176042f1effff */ 1276 1.369510155261156381121, /* 0x1.5e9837b062f4e0005 */ 1277 1.372187593620959988833, /* 0x1.5f47afa69436cfff1 */ 1278 1.374870266463378287715, /* 0x1.5ff77f6eb3f8cfffd */ 1279 1.377558184010425845733, /* 0x1.60a7a734a9742fff9 */ 1280 1.380251356531521533853, /* 0x1.6158272490016000c */ 1281 1.382949794301995272203, /* 0x1.6208ff6a8978a000f */ 1282 1.385653507605306700170, /* 0x1.62ba3032c0a280004 */ 1283 1.388362506772382154503, /* 0x1.636bb9a994784000f */ 1284 1.391076802081129493127, /* 0x1.641d9bfb29a7bfff6 */ 1285 1.393796403973427855412, /* 0x1.64cfd7545928b0002 */ 1286 1.396521322756352656542, /* 0x1.65826be167badfff8 */ 1287 1.399251568859207761660, /* 0x1.663559cf20826000c */ 1288 1.401987152677323100733, /* 0x1.66e8a14a29486fffc */ 1289 1.404728084651919228815, /* 0x1.679c427f5a4b6000b */ 1290 1.407474375243217723560, /* 0x1.68503d9ba0add000f */ 1291 1.410226034922914983815, /* 0x1.690492cbf6303fff9 */ 1292 1.412983074197955213304, /* 0x1.69b9423d7b548fff6 */ 1293}; 1294 1295/* All floating-point numbers can be put in one of these categories. */ 1296enum 1297 { 1298 FP_NAN, 1299# define FP_NAN FP_NAN 1300 FP_INFINITE, 1301# define FP_INFINITE FP_INFINITE 1302 FP_ZERO, 1303# define FP_ZERO FP_ZERO 1304 FP_SUBNORMAL, 1305# define FP_SUBNORMAL FP_SUBNORMAL 1306 FP_NORMAL 1307# define FP_NORMAL FP_NORMAL 1308 }; 1309 1310 1311int 1312__fpclassifyf (float x) 1313{ 1314 uint32_t wx; 1315 int retval = FP_NORMAL; 1316 1317 GET_FLOAT_WORD (wx, x); 1318 wx &= 0x7fffffff; 1319 if (wx == 0) 1320 retval = FP_ZERO; 1321 else if (wx < 0x800000) 1322 retval = FP_SUBNORMAL; 1323 else if (wx >= 0x7f800000) 1324 retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE; 1325 1326 return retval; 1327} 1328 1329 1330int 1331__isinff (float x) 1332{ 1333 int32_t ix,t; 1334 GET_FLOAT_WORD(ix,x); 1335 t = ix & 0x7fffffff; 1336 t ^= 0x7f800000; 1337 t |= -t; 1338 return ~(t >> 31) & (ix >> 30); 1339} 1340 1341/* Return nonzero value if arguments are unordered. */ 1342# define fpclassify(x) \ 1343 (sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassifyf (x)) 1344 1345# ifndef isunordered 1346# define isunordered(u, v) \ 1347 (__extension__ \ 1348 ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \ 1349 fpclassify (__u) == FP_NAN || fpclassify (__v) == FP_NAN; })) 1350# endif 1351 1352/* Return nonzero value if X is less than Y. */ 1353# ifndef isless 1354# define isless(x, y) \ 1355 (__extension__ \ 1356 ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ 1357 !isunordered (__x, __y) && __x < __y; })) 1358# endif 1359 1360/* Return nonzero value if X is greater than Y. */ 1361# ifndef isgreater 1362# define isgreater(x, y) \ 1363 (__extension__ \ 1364 ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ 1365 !isunordered (__x, __y) && __x > __y; })) 1366# endif 1367 1368union ieee754_double 1369 { 1370 double d; 1371 1372 /* This is the IEEE 754 double-precision format. */ 1373 struct 1374 { 1375#ifdef ROCKBOX_BIG_ENDIAN 1376 unsigned int negative:1; 1377 unsigned int exponent:11; 1378 /* Together these comprise the mantissa. */ 1379 unsigned int mantissa0:20; 1380 unsigned int mantissa1:32; 1381#else /* ROCKBOX_LITTLE_ENDIAN */ 1382 /* Together these comprise the mantissa. */ 1383 unsigned int mantissa1:32; 1384 unsigned int mantissa0:20; 1385 unsigned int exponent:11; 1386 unsigned int negative:1; 1387#endif /* ROCKBOX_LITTLE_ENDIAN */ 1388 } ieee; 1389 1390 /* This format makes it easier to see if a NaN is a signalling NaN. */ 1391 struct 1392 { 1393#ifdef ROCKBOX_BIG_ENDIAN 1394 unsigned int negative:1; 1395 unsigned int exponent:11; 1396 unsigned int quiet_nan:1; 1397 /* Together these comprise the mantissa. */ 1398 unsigned int mantissa0:19; 1399 unsigned int mantissa1:32; 1400#else /* ROCKBOX_LITTLE_ENDIAN */ 1401 /* Together these comprise the mantissa. */ 1402 unsigned int mantissa1:32; 1403 unsigned int mantissa0:19; 1404 unsigned int quiet_nan:1; 1405 unsigned int exponent:11; 1406 unsigned int negative:1; 1407#endif /* ROCKBOX_LITTLE_ENDIAN */ 1408 } ieee_nan; 1409 }; 1410 1411 1412static const volatile float TWOM100 = 7.88860905e-31; 1413static const volatile float TWO127 = 1.7014118346e+38; 1414 1415float rb_exp(float x) 1416{ 1417 static const float himark = 88.72283935546875; 1418 static const float lomark = -103.972084045410; 1419 /* Check for usual case. */ 1420 if (isless (x, himark) && isgreater (x, lomark)) 1421 { 1422 static const float THREEp42 = 13194139533312.0; 1423 static const float THREEp22 = 12582912.0; 1424 /* 1/ln(2). */ 1425#undef M_1_LN2 1426 static const float M_1_LN2 = 1.44269502163f; 1427 /* ln(2) */ 1428#undef M_LN2 1429 static const double M_LN2 = .6931471805599452862; 1430 1431 int tval; 1432 double x22, t, result, dx; 1433 float n, delta; 1434 union ieee754_double ex2_u; 1435#ifndef ROCKBOX 1436 fenv_t oldenv; 1437 1438 feholdexcept (&oldenv); 1439#endif 1440 1441#ifdef FE_TONEAREST 1442 fesetround (FE_TONEAREST); 1443#endif 1444 1445 /* Calculate n. */ 1446 n = x * M_1_LN2 + THREEp22; 1447 n -= THREEp22; 1448 dx = x - n*M_LN2; 1449 1450 /* Calculate t/512. */ 1451 t = dx + THREEp42; 1452 t -= THREEp42; 1453 dx -= t; 1454 1455 /* Compute tval = t. */ 1456 tval = (int) (t * 512.0); 1457 1458 if (t >= 0) 1459 delta = - __exp_deltatable[tval]; 1460 else 1461 delta = __exp_deltatable[-tval]; 1462 1463 /* Compute ex2 = 2^n e^(t/512+delta[t]). */ 1464 ex2_u.d = __exp_atable[tval+177]; 1465 ex2_u.ieee.exponent += (int) n; 1466 1467 /* Approximate e^(dx+delta) - 1, using a second-degree polynomial, 1468 with maximum error in [-2^-10-2^-28,2^-10+2^-28] 1469 less than 5e-11. */ 1470 x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta; 1471 1472 /* Return result. */ 1473#ifndef ROCKBOX 1474 fesetenv (&oldenv); 1475#endif 1476 1477 result = x22 * ex2_u.d + ex2_u.d; 1478 return (float) result; 1479 } 1480 /* Exceptional cases: */ 1481 else if (isless (x, himark)) 1482 { 1483 if (__isinff (x)) 1484 /* e^-inf == 0, with no error. */ 1485 return 0; 1486 else 1487 /* Underflow */ 1488 return TWOM100 * TWOM100; 1489 } 1490 else 1491 /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ 1492 return TWO127*x; 1493} 1494 1495 1496/* Division with rest, original. */ 1497div_t div(int x, int y) 1498{ 1499 div_t result; 1500 1501 result.quot = x / y; 1502 result.rem = x % y; 1503 1504 /* Addition from glibc-2.8: */ 1505 if(x >= 0 && result.rem < 0) 1506 { 1507 result.quot += 1; 1508 result.rem -= y; 1509 } 1510 1511 return result; 1512} 1513 1514 1515/* Placeholder function. */ 1516/* Originally defined in s_midi.c */ 1517void sys_listmididevs(void) 1518{ 1519} 1520 1521/* Placeholder function, 1522 as we do sleep in the core thread 1523 and not in the scheduler function. */ 1524/* Originally defined in s_inter.c */ 1525void sys_microsleep(int microsec) 1526{ 1527 (void) microsec; 1528} 1529 1530/* Get running time in milliseconds. */ 1531/* Originally defined in s_inter.c */ 1532extern uint64_t runningtime; 1533t_time sys_getrealtime(void) 1534{ 1535 return runningtime; 1536} 1537 1538/* Place holder, as we do no IPC. */ 1539/* Originally defined in s_inter.c */ 1540void glob_ping(void* dummy) 1541{ 1542 (void) dummy; 1543} 1544 1545/* Call to quit. */ 1546/* Originally defined in s_inter.c */ 1547extern bool quit; 1548void glob_quit(void* dummy) 1549{ 1550 (void) dummy; 1551 1552 static bool reentered = false; 1553 1554 if(!reentered) 1555 { 1556 reentered = true; 1557 1558 /* Close audio subsystem. */ 1559 /* Will be done by the main program: sys_close_audio(); */ 1560 1561 /* Stop main loop. */ 1562 quit = true; 1563 } 1564} 1565 1566/* Open file. Originally in s_main.c */ 1567void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir); 1568void openit(const char *dirname, const char *filename) 1569{ 1570 char* nameptr; 1571 char dirbuf[MAXPDSTRING]; 1572 1573 /* Workaround: If the file resides in the root directory, 1574 add a trailing slash to prevent directory part 1575 of the filename from being removed -- W.B. */ 1576 char ffilename[MAXPDSTRING]; 1577 ffilename[0] = '/'; 1578 ffilename[1] = '\0'; 1579 strcat(ffilename, filename); 1580 1581 int fd = open_via_path(dirname, ffilename, "", dirbuf, &nameptr, 1582 MAXPDSTRING, 0); 1583 if (fd) 1584 { 1585 close (fd); 1586 glob_evalfile(0, gensym(nameptr), gensym(dirbuf)); 1587 } 1588 else 1589 error("%s: can't open", filename); 1590} 1591 1592 1593/* Get current working directory. */ 1594extern char* filename; 1595char* rb_getcwd(char* buf, ssize_t size) 1596{ 1597 /* Initialize buffer. */ 1598 buf[0] = '\0'; 1599 1600 /* Search for the last slash. */ 1601 char* end_of_dir = strrchr(filename, '/'); 1602 int dirlen = end_of_dir - filename; 1603 1604 /* Check whether length of directory path is correct. 1605 If not, abort. */ 1606 if(size < dirlen || dirlen == 0) 1607 return NULL; 1608 1609 /* Copy current working directory to buffer. */ 1610 strncat(buf, filename, dirlen); 1611 return buf; 1612} 1613 1614 1615/* Execute instructions supplied on command-line. 1616 Basically a placeholder, because the only 1617 command line argument we get is the name of the .pd file. */ 1618/* Originally defined in s_main.c */ 1619extern t_namelist* sys_openlist; 1620void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv) 1621{ 1622 t_namelist *nl; 1623 char cwd[MAXPDSTRING]; 1624 1625 (void) dummy; 1626 (void) s; 1627 (void) argc; 1628 (void) argv; 1629 1630 /* Get current working directory. */ 1631 rb_getcwd(cwd, MAXPDSTRING); 1632 1633 /* open patches specifies with "-open" args */ 1634 for(nl = sys_openlist; nl; nl = nl->nl_next) 1635 openit(cwd, nl->nl_string); 1636 1637 namelist_free(sys_openlist); 1638 sys_openlist = 0; 1639} 1640 1641/* Fake GUI start. Originally in s_inter.c */ 1642static int defaultfontshit[] = { 1643 8, 5, 9, 10, 6, 10, 12, 7, 13, 14, 9, 17, 16, 10, 19, 24, 15, 28, 1644 24, 15, 28}; 1645extern t_binbuf* inbinbuf; 1646int sys_startgui(const char *guidir) 1647{ 1648 unsigned int i; 1649 t_atom zz[23]; 1650 char cmdbuf[4*MAXPDSTRING]; 1651 1652 (void) guidir; 1653 1654 inbinbuf = binbuf_new(); 1655 1656 if(!rb_getcwd(cmdbuf, MAXPDSTRING)) 1657 strcpy(cmdbuf, "."); 1658 1659 SETSYMBOL(zz, gensym(cmdbuf)); 1660 for (i = 1; i < 22; i++) 1661 SETFLOAT(zz + i, defaultfontshit[i-1]); 1662 SETFLOAT(zz+22,0); 1663 glob_initfromgui(0, 0, 23, zz); 1664 1665 return 0; 1666} 1667 1668/* Return default DAC block size. */ 1669/* Originally defined in s_main.c */ 1670int sys_getblksize(void) 1671{ 1672 return (DEFDACBLKSIZE); 1673} 1674 1675/* Find library directory and set it. */ 1676void sys_findlibdir(const char* filename) 1677{ 1678 char sbuf[MAXPDSTRING]; 1679 1680 (void) filename; 1681 1682 /* Make current working directory the system library directory. */ 1683 rb_getcwd(sbuf, MAXPDSTRING); 1684 sys_libdir = gensym(sbuf); 1685}