Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.6KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Util.cpp - Miscellaneous functions
  4. Copyright (C) 2002-2005 Nasca Octavian Paul
  5. Author: Nasca Octavian Paul
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. */
  11. #include "globals.h"
  12. #include "Util.h"
  13. #include <vector>
  14. #include <cassert>
  15. #include <cmath>
  16. #include <cstdio>
  17. #include <fstream>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <fcntl.h>
  21. #include <unistd.h>
  22. #include <errno.h>
  23. #include <string.h>
  24. #ifdef HAVE_SCHEDULER
  25. #include <sched.h>
  26. #endif
  27. #define errx(...) {}
  28. #ifndef errx
  29. #include <err.h>
  30. #endif
  31. #include <rtosc/rtosc.h>
  32. bool isPlugin = false;
  33. prng_t prng_state = 0x1234;
  34. /*
  35. * Transform the velocity according the scaling parameter (velocity sensing)
  36. */
  37. float VelF(float velocity, unsigned char scaling)
  38. {
  39. float x;
  40. x = powf(VELOCITY_MAX_SCALE, (64.0f - scaling) / 64.0f);
  41. if((scaling == 127) || (velocity > 0.99f))
  42. return 1.0f;
  43. else
  44. return powf(velocity, x);
  45. }
  46. /*
  47. * Get the detune in cents
  48. */
  49. float getdetune(unsigned char type,
  50. unsigned short int coarsedetune,
  51. unsigned short int finedetune)
  52. {
  53. float det = 0.0f, octdet = 0.0f, cdet = 0.0f, findet = 0.0f;
  54. //Get Octave
  55. int octave = coarsedetune / 1024;
  56. if(octave >= 8)
  57. octave -= 16;
  58. octdet = octave * 1200.0f;
  59. //Coarse and fine detune
  60. int cdetune = coarsedetune % 1024;
  61. if(cdetune > 512)
  62. cdetune -= 1024;
  63. int fdetune = finedetune - 8192;
  64. switch(type) {
  65. // case 1: is used for the default (see below)
  66. case 2:
  67. cdet = fabs(cdetune * 10.0f);
  68. findet = fabs(fdetune / 8192.0f) * 10.0f;
  69. break;
  70. case 3:
  71. cdet = fabs(cdetune * 100.0f);
  72. findet = powf(10, fabs(fdetune / 8192.0f) * 3.0f) / 10.0f - 0.1f;
  73. break;
  74. case 4:
  75. cdet = fabs(cdetune * 701.95500087f); //perfect fifth
  76. findet =
  77. (powf(2, fabs(fdetune / 8192.0f) * 12.0f) - 1.0f) / 4095 * 1200;
  78. break;
  79. //case ...: need to update N_DETUNE_TYPES, if you'll add more
  80. default:
  81. cdet = fabs(cdetune * 50.0f);
  82. findet = fabs(fdetune / 8192.0f) * 35.0f; //almost like "Paul's Sound Designer 2"
  83. break;
  84. }
  85. if(finedetune < 8192)
  86. findet = -findet;
  87. if(cdetune < 0)
  88. cdet = -cdet;
  89. det = octdet + cdet + findet;
  90. return det;
  91. }
  92. bool fileexists(const char *filename)
  93. {
  94. struct stat tmp;
  95. int result = stat(filename, &tmp);
  96. if(result >= 0)
  97. return true;
  98. return false;
  99. }
  100. void set_realtime()
  101. {
  102. #ifdef HAVE_SCHEDULER
  103. sched_param sc;
  104. sc.sched_priority = 60;
  105. //if you want get "sched_setscheduler undeclared" from compilation,
  106. //you can safely remove the folowing line:
  107. sched_setscheduler(0, SCHED_FIFO, &sc);
  108. //if (err==0) printf("Real-time");
  109. #endif
  110. }
  111. void os_sleep(long length)
  112. {
  113. usleep(length);
  114. }
  115. //!< maximum lenght a pid has on any POSIX system
  116. //!< this is an estimation, but more than 12 looks insane
  117. constexpr std::size_t max_pid_len = 12;
  118. //!< safe pid lenght guess, posix conform
  119. std::size_t os_guess_pid_length()
  120. {
  121. const char* pid_max_file = "/proc/sys/kernel/pid_max";
  122. if(-1 == access(pid_max_file, R_OK)) {
  123. return max_pid_len;
  124. }
  125. else {
  126. std::ifstream is(pid_max_file);
  127. if(!is.good())
  128. return max_pid_len;
  129. else {
  130. std::string s;
  131. is >> s;
  132. for(const auto& c : s)
  133. if(c < '0' || c > '9')
  134. return max_pid_len;
  135. return std::min(s.length(), max_pid_len);
  136. }
  137. }
  138. }
  139. //!< returns pid padded, posix conform
  140. std::string os_pid_as_padded_string()
  141. {
  142. char result_str[max_pid_len << 1];
  143. std::fill_n(result_str, max_pid_len, '0');
  144. std::size_t written = snprintf(result_str + max_pid_len, max_pid_len,
  145. "%d", (int)getpid());
  146. // the below pointer should never cause segfaults:
  147. return result_str + max_pid_len + written - os_guess_pid_length();
  148. }
  149. std::string legalizeFilename(std::string filename)
  150. {
  151. for(int i = 0; i < (int) filename.size(); ++i) {
  152. char c = filename[i];
  153. if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' ')))
  154. filename[i] = '_';
  155. }
  156. return filename;
  157. }
  158. void invSignal(float *sig, size_t len)
  159. {
  160. for(size_t i = 0; i < len; ++i)
  161. sig[i] *= -1.0f;
  162. }
  163. float SYNTH_T::numRandom()
  164. {
  165. return RND;
  166. }
  167. float interpolate(const float *data, size_t len, float pos)
  168. {
  169. assert(len > (size_t)pos + 1);
  170. const int l_pos = (int)pos,
  171. r_pos = l_pos + 1;
  172. const float leftness = pos - l_pos;
  173. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  174. }
  175. float cinterpolate(const float *data, size_t len, float pos)
  176. {
  177. const unsigned int i_pos = pos,
  178. l_pos = i_pos % len,
  179. r_pos = l_pos + 1 < len ? l_pos + 1 : 0;
  180. const float leftness = pos - i_pos;
  181. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  182. }
  183. char *rtosc_splat(const char *path, std::set<std::string> v)
  184. {
  185. char argT[v.size()+1];
  186. rtosc_arg_t arg[v.size()];
  187. unsigned i=0;
  188. for(auto &vv : v) {
  189. argT[i] = 's';
  190. arg[i].s = vv.c_str();
  191. i++;
  192. }
  193. argT[v.size()] = 0;
  194. size_t len = rtosc_amessage(0, 0, path, argT, arg);
  195. char *buf = new char[len];
  196. rtosc_amessage(buf, len, path, argT, arg);
  197. return buf;
  198. }