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.

253 lines
6.1KB

  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. namespace zyncarla {
  33. bool isPlugin = false;
  34. prng_t prng_state = 0x1234;
  35. /*
  36. * Transform the velocity according the scaling parameter (velocity sensing)
  37. */
  38. float VelF(float velocity, unsigned char scaling)
  39. {
  40. float x;
  41. x = powf(VELOCITY_MAX_SCALE, (64.0f - scaling) / 64.0f);
  42. if((scaling == 127) || (velocity > 0.99f))
  43. return 1.0f;
  44. else
  45. return powf(velocity, x);
  46. }
  47. /*
  48. * Get the detune in cents
  49. */
  50. float getdetune(unsigned char type,
  51. unsigned short int coarsedetune,
  52. unsigned short int finedetune)
  53. {
  54. float det = 0.0f, octdet = 0.0f, cdet = 0.0f, findet = 0.0f;
  55. //Get Octave
  56. int octave = coarsedetune / 1024;
  57. if(octave >= 8)
  58. octave -= 16;
  59. octdet = octave * 1200.0f;
  60. //Coarse and fine detune
  61. int cdetune = coarsedetune % 1024;
  62. if(cdetune > 512)
  63. cdetune -= 1024;
  64. int fdetune = finedetune - 8192;
  65. switch(type) {
  66. // case 1: is used for the default (see below)
  67. case 2:
  68. cdet = fabs(cdetune * 10.0f);
  69. findet = fabs(fdetune / 8192.0f) * 10.0f;
  70. break;
  71. case 3:
  72. cdet = fabs(cdetune * 100.0f);
  73. findet = powf(10, fabs(fdetune / 8192.0f) * 3.0f) / 10.0f - 0.1f;
  74. break;
  75. case 4:
  76. cdet = fabs(cdetune * 701.95500087f); //perfect fifth
  77. findet =
  78. (powf(2, fabs(fdetune / 8192.0f) * 12.0f) - 1.0f) / 4095 * 1200;
  79. break;
  80. //case ...: need to update N_DETUNE_TYPES, if you'll add more
  81. default:
  82. cdet = fabs(cdetune * 50.0f);
  83. findet = fabs(fdetune / 8192.0f) * 35.0f; //almost like "Paul's Sound Designer 2"
  84. break;
  85. }
  86. if(finedetune < 8192)
  87. findet = -findet;
  88. if(cdetune < 0)
  89. cdet = -cdet;
  90. det = octdet + cdet + findet;
  91. return det;
  92. }
  93. bool fileexists(const char *filename)
  94. {
  95. struct stat tmp;
  96. int result = stat(filename, &tmp);
  97. if(result >= 0)
  98. return true;
  99. return false;
  100. }
  101. void set_realtime()
  102. {
  103. #ifdef HAVE_SCHEDULER
  104. sched_param sc;
  105. sc.sched_priority = 60;
  106. //if you want get "sched_setscheduler undeclared" from compilation,
  107. //you can safely remove the folowing line:
  108. sched_setscheduler(0, SCHED_FIFO, &sc);
  109. //if (err==0) printf("Real-time");
  110. #endif
  111. }
  112. #ifdef WIN32
  113. #include <windows.h>
  114. //https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw
  115. void os_usleep(long usec)
  116. {
  117. HANDLE timer;
  118. LARGE_INTEGER ft;
  119. ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
  120. timer = CreateWaitableTimer(NULL, TRUE, NULL);
  121. SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
  122. WaitForSingleObject(timer, INFINITE);
  123. CloseHandle(timer);
  124. }
  125. #else
  126. void os_usleep(long length)
  127. {
  128. usleep(length);
  129. }
  130. #endif
  131. //!< maximum lenght a pid has on any POSIX system
  132. //!< this is an estimation, but more than 12 looks insane
  133. constexpr std::size_t max_pid_len = 12;
  134. //!< safe pid lenght guess, posix conform
  135. std::size_t os_guess_pid_length()
  136. {
  137. const char* pid_max_file = "/proc/sys/kernel/pid_max";
  138. if(-1 == access(pid_max_file, R_OK)) {
  139. return max_pid_len;
  140. }
  141. else {
  142. std::ifstream is(pid_max_file);
  143. if(!is.good())
  144. return max_pid_len;
  145. else {
  146. std::string s;
  147. is >> s;
  148. for(const auto& c : s)
  149. if(c < '0' || c > '9')
  150. return max_pid_len;
  151. return std::min(s.length(), max_pid_len);
  152. }
  153. }
  154. }
  155. //!< returns pid padded, posix conform
  156. std::string os_pid_as_padded_string()
  157. {
  158. char result_str[max_pid_len << 1];
  159. std::fill_n(result_str, max_pid_len, '0');
  160. std::size_t written = snprintf(result_str + max_pid_len, max_pid_len,
  161. "%d", (int)getpid());
  162. // the below pointer should never cause segfaults:
  163. return result_str + max_pid_len + written - os_guess_pid_length();
  164. }
  165. std::string legalizeFilename(std::string filename)
  166. {
  167. for(int i = 0; i < (int) filename.size(); ++i) {
  168. char c = filename[i];
  169. if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' ')))
  170. filename[i] = '_';
  171. }
  172. return filename;
  173. }
  174. void invSignal(float *sig, size_t len)
  175. {
  176. for(size_t i = 0; i < len; ++i)
  177. sig[i] *= -1.0f;
  178. }
  179. float SYNTH_T::numRandom()
  180. {
  181. return RND;
  182. }
  183. float interpolate(const float *data, size_t len, float pos)
  184. {
  185. assert(len > (size_t)pos + 1);
  186. const int l_pos = (int)pos,
  187. r_pos = l_pos + 1;
  188. const float leftness = pos - l_pos;
  189. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  190. }
  191. float cinterpolate(const float *data, size_t len, float pos)
  192. {
  193. const unsigned int i_pos = pos,
  194. l_pos = i_pos % len,
  195. r_pos = l_pos + 1 < len ? l_pos + 1 : 0;
  196. const float leftness = pos - i_pos;
  197. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  198. }
  199. char *rtosc_splat(const char *path, std::set<std::string> v)
  200. {
  201. char argT[v.size()+1];
  202. rtosc_arg_t arg[v.size()];
  203. unsigned i=0;
  204. for(auto &vv : v) {
  205. argT[i] = 's';
  206. arg[i].s = vv.c_str();
  207. i++;
  208. }
  209. argT[v.size()] = 0;
  210. size_t len = rtosc_amessage(0, 0, path, argT, arg);
  211. char *buf = new char[len];
  212. rtosc_amessage(buf, len, path, argT, arg);
  213. return buf;
  214. }
  215. }