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.

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