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.

223 lines
5.5KB

  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 modify
  7. it under the terms of version 2 of the GNU General Public License
  8. as published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License (version 2 or later) for more details.
  13. You should have received a copy of the GNU General Public License (version 2)
  14. along with this program; if not, write to the Free Software Foundation,
  15. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include "Util.h"
  18. #include <vector>
  19. #include <cassert>
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include <err.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <fcntl.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <string.h>
  29. #include <sched.h>
  30. prng_t prng_state = 0x1234;
  31. Config config;
  32. float *denormalkillbuf;
  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);
  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. sched_param sc;
  102. sc.sched_priority = 60;
  103. //if you want get "sched_setscheduler undeclared" from compilation,
  104. //you can safely remove the folowing line:
  105. sched_setscheduler(0, SCHED_FIFO, &sc);
  106. //if (err==0) printf("Real-time");
  107. }
  108. void os_sleep(long length)
  109. {
  110. usleep(length);
  111. }
  112. std::string legalizeFilename(std::string filename)
  113. {
  114. for(int i = 0; i < (int) filename.size(); ++i) {
  115. char c = filename[i];
  116. if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' ')))
  117. filename[i] = '_';
  118. }
  119. return filename;
  120. }
  121. void invSignal(float *sig, size_t len)
  122. {
  123. for(size_t i = 0; i < len; ++i)
  124. sig[i] *= -1.0f;
  125. }
  126. //Some memory pools for short term buffer use
  127. //(avoid the use of new in RT thread(s))
  128. struct pool_entry {
  129. bool free;
  130. float *dat;
  131. };
  132. typedef std::vector<pool_entry> pool_t;
  133. typedef pool_t::iterator pool_itr_t;
  134. pool_t pool;
  135. float *getTmpBuffer()
  136. {
  137. for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr)
  138. if(itr->free) { //Use Pool
  139. itr->free = false;
  140. return itr->dat;
  141. }
  142. pool_entry p; //Extend Pool
  143. p.free = false;
  144. p.dat = new float[synth->buffersize];
  145. pool.push_back(p);
  146. return p.dat;
  147. }
  148. void returnTmpBuffer(float *buf)
  149. {
  150. for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr)
  151. if(itr->dat == buf) { //Return to Pool
  152. itr->free = true;
  153. return;
  154. }
  155. fprintf(stderr,
  156. "ERROR: invalid buffer returned %s %d\n",
  157. __FILE__,
  158. __LINE__);
  159. }
  160. void clearTmpBuffers(void)
  161. {
  162. for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr) {
  163. if(!itr->free) //Warn about used buffers
  164. warn("Temporary buffer (%p) about to be freed may be in use",
  165. itr->dat);
  166. delete [] itr->dat;
  167. }
  168. pool.clear();
  169. }
  170. float SYNTH_T::numRandom()
  171. {
  172. return RND;
  173. }
  174. float interpolate(const float *data, size_t len, float pos)
  175. {
  176. assert(len > (size_t)pos + 1);
  177. const int l_pos = (int)pos,
  178. r_pos = l_pos + 1;
  179. const float leftness = pos - l_pos;
  180. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  181. }
  182. float cinterpolate(const float *data, size_t len, float pos)
  183. {
  184. const int l_pos = ((int)pos) % len,
  185. r_pos = (l_pos + 1) % len;
  186. const float leftness = pos - l_pos;
  187. return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
  188. }