No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

16805 líneas
424KB

  1. /* CLM (Music V) implementation */
  2. #include "mus-config.h"
  3. #if USE_SND
  4. #include "snd.h"
  5. #endif
  6. #include <stddef.h>
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <errno.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #ifndef _MSC_VER
  14. #include <unistd.h>
  15. #else
  16. #include <io.h>
  17. #pragma warning(disable: 4244)
  18. #endif
  19. #include "_sndlib.h"
  20. #include "clm.h"
  21. #include "clm-strings.h"
  22. #if HAVE_GSL
  23. #include <gsl/gsl_complex.h>
  24. #include <gsl/gsl_complex_math.h>
  25. #endif
  26. #if HAVE_FFTW3
  27. #include <fftw3.h>
  28. #endif
  29. #if HAVE_COMPLEX_TRIG
  30. #include <complex.h>
  31. #endif
  32. #if (!DISABLE_SINCOS) && defined(__GNUC__) && defined(__linux__)
  33. #define HAVE_SINCOS 1
  34. void sincos(double x, double *sin, double *cos);
  35. #else
  36. #define HAVE_SINCOS 0
  37. #endif
  38. #ifndef TWO_PI
  39. #define TWO_PI (2.0 * M_PI)
  40. #endif
  41. struct mus_any_class {
  42. int type;
  43. char *name;
  44. void (*release)(mus_any *ptr);
  45. char *(*describe)(mus_any *ptr); /* caller should free the string */
  46. bool (*equalp)(mus_any *gen1, mus_any *gen2);
  47. mus_float_t *(*data)(mus_any *ptr);
  48. mus_float_t *(*set_data)(mus_any *ptr, mus_float_t *new_data);
  49. mus_long_t (*length)(mus_any *ptr);
  50. mus_long_t (*set_length)(mus_any *ptr, mus_long_t new_length);
  51. mus_float_t (*frequency)(mus_any *ptr);
  52. mus_float_t (*set_frequency)(mus_any *ptr, mus_float_t new_freq);
  53. mus_float_t (*phase)(mus_any *ptr);
  54. mus_float_t (*set_phase)(mus_any *ptr, mus_float_t new_phase);
  55. mus_float_t (*scaler)(mus_any *ptr);
  56. mus_float_t (*set_scaler)(mus_any *ptr, mus_float_t val);
  57. mus_float_t (*increment)(mus_any *ptr);
  58. mus_float_t (*set_increment)(mus_any *ptr, mus_float_t val);
  59. mus_float_t (*run)(mus_any *gen, mus_float_t arg1, mus_float_t arg2);
  60. mus_clm_extended_t extended_type;
  61. void *(*closure)(mus_any *gen);
  62. int (*channels)(mus_any *ptr);
  63. mus_float_t (*offset)(mus_any *ptr);
  64. mus_float_t (*set_offset)(mus_any *ptr, mus_float_t val);
  65. mus_float_t (*width)(mus_any *ptr);
  66. mus_float_t (*set_width)(mus_any *ptr, mus_float_t val);
  67. mus_float_t (*xcoeff)(mus_any *ptr, int index);
  68. mus_float_t (*set_xcoeff)(mus_any *ptr, int index, mus_float_t val);
  69. mus_long_t (*hop)(mus_any *ptr);
  70. mus_long_t (*set_hop)(mus_any *ptr, mus_long_t new_length);
  71. mus_long_t (*ramp)(mus_any *ptr);
  72. mus_long_t (*set_ramp)(mus_any *ptr, mus_long_t new_length);
  73. mus_float_t (*read_sample)(mus_any *ptr, mus_long_t samp, int chan);
  74. mus_float_t (*write_sample)(mus_any *ptr, mus_long_t samp, int chan, mus_float_t data);
  75. char *(*file_name)(mus_any *ptr);
  76. int (*end)(mus_any *ptr);
  77. mus_long_t (*location)(mus_any *ptr);
  78. mus_long_t (*set_location)(mus_any *ptr, mus_long_t loc);
  79. int (*channel)(mus_any *ptr);
  80. mus_float_t (*ycoeff)(mus_any *ptr, int index);
  81. mus_float_t (*set_ycoeff)(mus_any *ptr, int index, mus_float_t val);
  82. mus_float_t *(*xcoeffs)(mus_any *ptr);
  83. mus_float_t *(*ycoeffs)(mus_any *ptr);
  84. void (*reset)(mus_any *ptr);
  85. void *(*set_closure)(mus_any *gen, void *e);
  86. mus_any *(*copy)(mus_any *ptr);
  87. };
  88. enum {MUS_OSCIL, MUS_NCOS, MUS_DELAY, MUS_COMB, MUS_NOTCH, MUS_ALL_PASS,
  89. MUS_TABLE_LOOKUP, MUS_SQUARE_WAVE, MUS_SAWTOOTH_WAVE, MUS_TRIANGLE_WAVE, MUS_PULSE_TRAIN,
  90. MUS_RAND, MUS_RAND_INTERP, MUS_ASYMMETRIC_FM, MUS_ONE_ZERO, MUS_ONE_POLE, MUS_TWO_ZERO, MUS_TWO_POLE, MUS_FORMANT,
  91. MUS_SRC, MUS_GRANULATE, MUS_WAVE_TRAIN,
  92. MUS_FILTER, MUS_FIR_FILTER, MUS_IIR_FILTER, MUS_CONVOLVE, MUS_ENV, MUS_LOCSIG,
  93. MUS_READIN, MUS_FILE_TO_SAMPLE, MUS_FILE_TO_FRAMPLE,
  94. MUS_SAMPLE_TO_FILE, MUS_FRAMPLE_TO_FILE, MUS_PHASE_VOCODER,
  95. MUS_MOVING_AVERAGE, MUS_MOVING_MAX, MUS_MOVING_NORM, MUS_NSIN, MUS_SSB_AM, MUS_POLYSHAPE, MUS_FILTERED_COMB,
  96. MUS_MOVE_SOUND, MUS_NRXYSIN, MUS_NRXYCOS, MUS_POLYWAVE, MUS_FIRMANT, MUS_FORMANT_BANK,
  97. MUS_ONE_POLE_ALL_PASS, MUS_COMB_BANK, MUS_ALL_PASS_BANK, MUS_FILTERED_COMB_BANK, MUS_OSCIL_BANK,
  98. MUS_PULSED_ENV, MUS_RXYKSIN, MUS_RXYKCOS,
  99. MUS_INITIAL_GEN_TAG};
  100. mus_any_class *mus_generator_class(mus_any *ptr) {return(ptr->core);}
  101. void mus_generator_set_extended_type(mus_any_class *p, mus_clm_extended_t extended_type) {p->extended_type = extended_type;}
  102. void mus_generator_set_length(mus_any_class *p, mus_long_t (*length)(mus_any *ptr)) {p->length = length;}
  103. void mus_generator_set_scaler(mus_any_class *p, mus_float_t (*scaler)(mus_any *ptr)) {p->scaler = scaler;}
  104. void mus_generator_set_channels(mus_any_class *p, int (*channels)(mus_any *ptr)) {p->channels = channels;}
  105. void mus_generator_set_location(mus_any_class *p, mus_long_t (*location)(mus_any *ptr)) {p->location = location;}
  106. void mus_generator_set_set_location(mus_any_class *p, mus_long_t (*set_location)(mus_any *ptr, mus_long_t loc)) {p->set_location = set_location;}
  107. void mus_generator_set_read_sample(mus_any_class *p, mus_float_t (*read_sample)(mus_any *ptr, mus_long_t samp, int chan)) {p->read_sample = read_sample;}
  108. void mus_generator_set_channel(mus_any_class *p, int (*channel)(mus_any *ptr)) {p->channel = channel;}
  109. void mus_generator_set_file_name(mus_any_class *p, char *(*file_name)(mus_any *ptr)) {p->file_name = file_name;}
  110. mus_any_class *mus_make_generator(int type, char *name,
  111. void (*release)(mus_any *ptr),
  112. char *(*describe)(mus_any *ptr),
  113. bool (*equalp)(mus_any *gen1, mus_any *gen2))
  114. {
  115. mus_any_class *p;
  116. p = (mus_any_class *)calloc(1, sizeof(mus_any_class));
  117. p->type = type;
  118. p->name = name;
  119. p->release = release;
  120. p->describe = describe;
  121. p->equalp = equalp;
  122. return(p);
  123. }
  124. static int mus_generator_type = MUS_INITIAL_GEN_TAG;
  125. int mus_make_generator_type(void) {return(mus_generator_type++);}
  126. static const char *interp_name[] = {"step", "linear", "sinusoidal", "all-pass", "lagrange", "bezier", "hermite"};
  127. static const char *interp_type_to_string(int type)
  128. {
  129. if (mus_is_interp_type(type))
  130. return(interp_name[type]);
  131. return("unknown");
  132. }
  133. static mus_float_t sampling_rate = MUS_DEFAULT_SAMPLING_RATE;
  134. static mus_float_t w_rate = (TWO_PI / MUS_DEFAULT_SAMPLING_RATE);
  135. static mus_float_t float_equal_fudge_factor = 0.0000001;
  136. mus_float_t mus_float_equal_fudge_factor(void) {return(float_equal_fudge_factor);}
  137. mus_float_t mus_set_float_equal_fudge_factor(mus_float_t val)
  138. {
  139. mus_float_t prev;
  140. prev = float_equal_fudge_factor;
  141. float_equal_fudge_factor = val;
  142. return(prev);
  143. }
  144. static int array_print_length = MUS_DEFAULT_ARRAY_PRINT_LENGTH;
  145. int mus_array_print_length(void) {return(array_print_length);}
  146. int mus_set_array_print_length(int val)
  147. {
  148. int prev;
  149. prev = array_print_length;
  150. if (val >= 0) array_print_length = val;
  151. return(prev);
  152. }
  153. static mus_long_t clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE;
  154. mus_long_t mus_file_buffer_size(void) {return(clm_file_buffer_size);}
  155. mus_long_t mus_set_file_buffer_size(mus_long_t size)
  156. {
  157. /* this is set in with-sound, among other places */
  158. mus_long_t prev;
  159. prev = clm_file_buffer_size;
  160. clm_file_buffer_size = size;
  161. return(prev);
  162. }
  163. mus_float_t mus_radians_to_hz(mus_float_t rads) {return(rads / w_rate);}
  164. mus_float_t mus_hz_to_radians(mus_float_t hz) {return(hz * w_rate);}
  165. mus_float_t mus_degrees_to_radians(mus_float_t degree) {return(degree * TWO_PI / 360.0);}
  166. mus_float_t mus_radians_to_degrees(mus_float_t rads) {return(rads * 360.0 / TWO_PI);}
  167. mus_float_t mus_db_to_linear(mus_float_t x) {return(pow(10.0, x / 20.0));}
  168. mus_float_t mus_linear_to_db(mus_float_t x) {if (x > 0.0) return(20.0 * log10(x)); return(-100.0);}
  169. mus_float_t mus_odd_multiple(mus_float_t x, mus_float_t y) {mus_long_t f; f = (mus_long_t)floor(x); return(y * ((f & 1) ? f : (f + 1)));}
  170. mus_float_t mus_even_multiple(mus_float_t x, mus_float_t y) {mus_long_t f; f = (mus_long_t)floor(x); return(y * ((f & 1) ? (f + 1) : f));}
  171. mus_float_t mus_odd_weight(mus_float_t x) {mus_long_t f; f = (mus_long_t)floor(x); return(1.0 - fabs(x - ((f & 1) ? f : (f + 1))));}
  172. mus_float_t mus_even_weight(mus_float_t x) {mus_long_t f; f = (mus_long_t)floor(x); return(1.0 - fabs(x - ((f & 1) ? (f + 1) : f)));}
  173. mus_float_t mus_srate(void) {return(sampling_rate);}
  174. mus_float_t mus_set_srate(mus_float_t val)
  175. {
  176. mus_float_t prev;
  177. prev = sampling_rate;
  178. if (val > 0.0)
  179. {
  180. sampling_rate = val;
  181. w_rate = (TWO_PI / sampling_rate);
  182. }
  183. return(prev);
  184. }
  185. mus_long_t mus_seconds_to_samples(mus_float_t secs) {return((mus_long_t)(secs * sampling_rate));}
  186. mus_float_t mus_samples_to_seconds(mus_long_t samps) {return((mus_float_t)((mus_float_t)samps / (mus_float_t)sampling_rate));}
  187. #define DESCRIBE_BUFFER_SIZE 2048
  188. #define STR_SIZE 128
  189. static char *float_array_to_string(mus_float_t *arr, int len, int loc)
  190. {
  191. /* %g is needed here rather than %f -- otherwise the number strings can be any size */
  192. #define MAX_NUM_SIZE 64
  193. char *base, *str;
  194. int i, lim, size = 512;
  195. if (arr == NULL)
  196. {
  197. str = (char *)malloc(4 * sizeof(char));
  198. snprintf(str, 4, "nil");
  199. return(str);
  200. }
  201. lim = (array_print_length + 4) * MAX_NUM_SIZE; /* 4 for possible bounds below */
  202. if (lim > size) size = lim;
  203. if (loc < 0) loc = 0;
  204. base = (char *)calloc(size, sizeof(char));
  205. str = (char *)malloc(STR_SIZE * sizeof(char));
  206. if (len > 0)
  207. {
  208. int k;
  209. snprintf(base, size, "[");
  210. lim = len;
  211. if (lim > array_print_length) lim = array_print_length;
  212. k = loc;
  213. if (k >= len) k = 0;
  214. for (i = 0; i < lim - 1; i++)
  215. {
  216. snprintf(str, STR_SIZE, "%.3g ", arr[k]);
  217. strcat(base, str);
  218. if ((int)(strlen(base) + MAX_NUM_SIZE) > size)
  219. {
  220. base = (char *)realloc(base, size * 2 * sizeof(char));
  221. base[size] = 0;
  222. size *= 2;
  223. }
  224. k++;
  225. if (k >= len) k = 0;
  226. }
  227. snprintf(str, STR_SIZE, "%.3g%s", arr[k], (len > lim) ? "..." : "]");
  228. strcat(base, str);
  229. }
  230. else snprintf(base, size, "[]");
  231. if (len > lim)
  232. {
  233. /* print ranges */
  234. int min_loc = 0, max_loc = 0;
  235. mus_float_t min_val, max_val;
  236. min_val = arr[0];
  237. max_val = arr[0];
  238. for (i = 1; i < len; i++)
  239. {
  240. if (arr[i] < min_val) {min_val = arr[i]; min_loc = i;}
  241. if (arr[i] > max_val) {max_val = arr[i]; max_loc = i;}
  242. }
  243. snprintf(str, STR_SIZE, "(%d: %.3g, %d: %.3g)]", min_loc, min_val, max_loc, max_val);
  244. strcat(base, str);
  245. }
  246. free(str);
  247. return(base);
  248. }
  249. static char *clm_array_to_string(mus_any **gens, int num_gens, const char *name, const char *indent)
  250. {
  251. char *descr = NULL;
  252. if ((gens) && (num_gens > 0))
  253. {
  254. int i, len = 0;
  255. char **descrs;
  256. descrs = (char **)calloc(num_gens, sizeof(char *));
  257. for (i = 0; i < num_gens; i++)
  258. {
  259. if (gens[i])
  260. {
  261. char *str = NULL;
  262. descrs[i] = mus_format("\n%s[%d]: %s", indent, i, str = mus_describe(gens[i]));
  263. if (str) free(str);
  264. }
  265. else descrs[i] = mus_format("\n%s[%d]: nil", indent, i);
  266. len += strlen(descrs[i]);
  267. }
  268. len += (64 + strlen(name));
  269. descr = (char *)malloc(len * sizeof(char));
  270. snprintf(descr, len, "%s[%d]:", name, num_gens);
  271. for (i = 0; i < num_gens; i++)
  272. {
  273. strcat(descr, descrs[i]);
  274. free(descrs[i]);
  275. }
  276. free(descrs);
  277. }
  278. else
  279. {
  280. descr = (char *)malloc(128 * sizeof(char));
  281. snprintf(descr, 128, "%s: nil", name);
  282. }
  283. return(descr);
  284. }
  285. static char *int_array_to_string(int *arr, int num_ints, const char *name)
  286. {
  287. #define MAX_INT_SIZE 32
  288. char *descr = NULL;
  289. if ((arr) && (num_ints > 0))
  290. {
  291. int i, len;
  292. char *intstr;
  293. len = num_ints * MAX_INT_SIZE + 64;
  294. descr = (char *)calloc(len, sizeof(char));
  295. intstr = (char *)malloc(MAX_INT_SIZE * sizeof(char));
  296. snprintf(descr, len, "%s[%d]: (", name, num_ints);
  297. for (i = 0; i < num_ints - 1; i++)
  298. {
  299. snprintf(intstr, MAX_INT_SIZE, "%d ", arr[i]);
  300. strcat(descr, intstr);
  301. }
  302. snprintf(intstr, MAX_INT_SIZE, "%d)", arr[num_ints - 1]);
  303. strcat(descr, intstr);
  304. free(intstr);
  305. }
  306. else
  307. {
  308. descr = (char *)malloc(128 * sizeof(char));
  309. snprintf(descr, 128, "%s: nil", name);
  310. }
  311. return(descr);
  312. }
  313. /* ---------------- generic functions ---------------- */
  314. #define check_gen(Ptr, Name) ((Ptr) ? true : (!mus_error(MUS_NO_GEN, "null generator passed to %s", Name)))
  315. int mus_type(mus_any *ptr)
  316. {
  317. return(((check_gen(ptr, S_mus_type)) && (ptr->core)) ? ptr->core->type : -1);
  318. }
  319. const char *mus_name(mus_any *ptr)
  320. {
  321. return((ptr == NULL) ? "null" : ptr->core->name);
  322. }
  323. void mus_free(mus_any *gen)
  324. {
  325. if (gen)
  326. (*(gen->core->release))(gen);
  327. }
  328. char *mus_describe(mus_any *gen)
  329. {
  330. if (gen == NULL)
  331. return(mus_strdup((char *)"null"));
  332. if ((gen->core) && (gen->core->describe))
  333. return((*(gen->core->describe))(gen));
  334. else mus_error(MUS_NO_DESCRIBE, "can't describe %s", mus_name(gen));
  335. return(NULL);
  336. }
  337. bool mus_equalp(mus_any *p1, mus_any *p2)
  338. {
  339. if ((p1) && (p2))
  340. {
  341. if ((p1->core)->equalp)
  342. return((*((p1->core)->equalp))(p1, p2));
  343. else return(p1 == p2);
  344. }
  345. return(true); /* (eq nil nil) */
  346. }
  347. void mus_reset(mus_any *gen)
  348. {
  349. if ((check_gen(gen, S_mus_reset)) &&
  350. (gen->core->reset))
  351. (*(gen->core->reset))(gen);
  352. else mus_error(MUS_NO_RESET, "can't reset %s", mus_name(gen));
  353. }
  354. mus_any *mus_copy(mus_any *gen)
  355. {
  356. if ((check_gen(gen, S_mus_copy)) &&
  357. (gen->core->copy))
  358. return((*(gen->core->copy))(gen));
  359. else mus_error(MUS_NO_COPY, "can't copy %s", mus_name(gen));
  360. return(NULL);
  361. }
  362. mus_float_t mus_frequency(mus_any *gen)
  363. {
  364. if ((check_gen(gen, S_mus_frequency)) &&
  365. (gen->core->frequency))
  366. return((*(gen->core->frequency))(gen));
  367. return((mus_float_t)mus_error(MUS_NO_FREQUENCY, "can't get %s's frequency", mus_name(gen)));
  368. }
  369. mus_float_t mus_set_frequency(mus_any *gen, mus_float_t val)
  370. {
  371. if ((check_gen(gen, S_set S_mus_frequency)) &&
  372. (gen->core->set_frequency))
  373. return((*(gen->core->set_frequency))(gen, val));
  374. return((mus_float_t)mus_error(MUS_NO_FREQUENCY, "can't set %s's frequency", mus_name(gen)));
  375. }
  376. mus_float_t mus_phase(mus_any *gen)
  377. {
  378. if ((check_gen(gen, S_mus_phase)) &&
  379. (gen->core->phase))
  380. return((*(gen->core->phase))(gen));
  381. return((mus_float_t)mus_error(MUS_NO_PHASE, "can't get %s's phase", mus_name(gen)));
  382. }
  383. mus_float_t mus_set_phase(mus_any *gen, mus_float_t val)
  384. {
  385. if ((check_gen(gen, S_set S_mus_phase)) &&
  386. (gen->core->set_phase))
  387. return((*(gen->core->set_phase))(gen, val));
  388. return((mus_float_t)mus_error(MUS_NO_PHASE, "can't set %s's phase", mus_name(gen)));
  389. }
  390. mus_float_t mus_scaler(mus_any *gen)
  391. {
  392. if ((check_gen(gen, S_mus_scaler)) &&
  393. (gen->core->scaler))
  394. return((*(gen->core->scaler))(gen));
  395. return((mus_float_t)mus_error(MUS_NO_SCALER, "can't get %s's scaler", mus_name(gen)));
  396. }
  397. mus_float_t mus_set_scaler(mus_any *gen, mus_float_t val)
  398. {
  399. if ((check_gen(gen, S_set S_mus_scaler)) &&
  400. (gen->core->set_scaler))
  401. return((*(gen->core->set_scaler))(gen, val));
  402. return((mus_float_t)mus_error(MUS_NO_SCALER, "can't set %s's scaler", mus_name(gen)));
  403. }
  404. mus_float_t mus_feedforward(mus_any *gen) /* shares "scaler" */
  405. {
  406. if ((check_gen(gen, S_mus_feedforward)) &&
  407. (gen->core->scaler))
  408. return((*(gen->core->scaler))(gen));
  409. return((mus_float_t)mus_error(MUS_NO_FEEDFORWARD, "can't get %s's feedforward", mus_name(gen)));
  410. }
  411. mus_float_t mus_set_feedforward(mus_any *gen, mus_float_t val)
  412. {
  413. if ((check_gen(gen, S_set S_mus_feedforward)) &&
  414. (gen->core->set_scaler))
  415. return((*(gen->core->set_scaler))(gen, val));
  416. return((mus_float_t)mus_error(MUS_NO_FEEDFORWARD, "can't set %s's feedforward", mus_name(gen)));
  417. }
  418. mus_float_t mus_offset(mus_any *gen)
  419. {
  420. if ((check_gen(gen, S_mus_offset)) &&
  421. (gen->core->offset))
  422. return((*(gen->core->offset))(gen));
  423. return((mus_float_t)mus_error(MUS_NO_OFFSET, "can't get %s's offset", mus_name(gen)));
  424. }
  425. mus_float_t mus_set_offset(mus_any *gen, mus_float_t val)
  426. {
  427. if ((check_gen(gen, S_set S_mus_offset)) &&
  428. (gen->core->set_offset))
  429. return((*(gen->core->set_offset))(gen, val));
  430. return((mus_float_t)mus_error(MUS_NO_OFFSET, "can't set %s's offset", mus_name(gen)));
  431. }
  432. mus_float_t mus_width(mus_any *gen)
  433. {
  434. if ((check_gen(gen, S_mus_width)) &&
  435. (gen->core->width))
  436. return((*(gen->core->width))(gen));
  437. return((mus_float_t)mus_error(MUS_NO_WIDTH, "can't get %s's width", mus_name(gen)));
  438. }
  439. mus_float_t mus_set_width(mus_any *gen, mus_float_t val)
  440. {
  441. if ((check_gen(gen, S_set S_mus_width)) &&
  442. (gen->core->set_width))
  443. return((*(gen->core->set_width))(gen, val));
  444. return((mus_float_t)mus_error(MUS_NO_WIDTH, "can't set %s's width", mus_name(gen)));
  445. }
  446. mus_float_t mus_increment(mus_any *gen)
  447. {
  448. if ((check_gen(gen, S_mus_increment)) &&
  449. (gen->core->increment))
  450. return((*(gen->core->increment))(gen));
  451. return((mus_float_t)mus_error(MUS_NO_INCREMENT, "can't get %s's increment", mus_name(gen)));
  452. }
  453. mus_float_t mus_set_increment(mus_any *gen, mus_float_t val)
  454. {
  455. if ((check_gen(gen, S_set S_mus_increment)) &&
  456. (gen->core->set_increment))
  457. return((*(gen->core->set_increment))(gen, val));
  458. return((mus_float_t)mus_error(MUS_NO_INCREMENT, "can't set %s's increment", mus_name(gen)));
  459. }
  460. mus_float_t mus_feedback(mus_any *gen) /* shares "increment" */
  461. {
  462. if ((check_gen(gen, S_mus_feedback)) &&
  463. (gen->core->increment))
  464. return((*(gen->core->increment))(gen));
  465. return((mus_float_t)mus_error(MUS_NO_FEEDBACK, "can't get %s's feedback", mus_name(gen)));
  466. }
  467. mus_float_t mus_set_feedback(mus_any *gen, mus_float_t val)
  468. {
  469. if ((check_gen(gen, S_set S_mus_feedback)) &&
  470. (gen->core->set_increment))
  471. return((*(gen->core->set_increment))(gen, val));
  472. return((mus_float_t)mus_error(MUS_NO_FEEDBACK, "can't set %s's feedback", mus_name(gen)));
  473. }
  474. void *mus_environ(mus_any *gen)
  475. {
  476. if (check_gen(gen, "mus-environ"))
  477. return((*(gen->core->closure))(gen));
  478. return(NULL);
  479. }
  480. void *mus_set_environ(mus_any *gen, void *e)
  481. {
  482. if (check_gen(gen, S_set "mus-environ"))
  483. return((*(gen->core->set_closure))(gen, e));
  484. return(NULL);
  485. }
  486. mus_float_t mus_run(mus_any *gen, mus_float_t arg1, mus_float_t arg2)
  487. {
  488. if ((check_gen(gen, "mus-run")) &&
  489. (gen->core->run))
  490. return((*(gen->core->run))(gen, arg1, arg2));
  491. return((mus_float_t)mus_error(MUS_NO_RUN, "can't run %s", mus_name(gen)));
  492. }
  493. mus_long_t mus_length(mus_any *gen)
  494. {
  495. if ((check_gen(gen, S_mus_length)) &&
  496. (gen->core->length))
  497. return((*(gen->core->length))(gen));
  498. return(mus_error(MUS_NO_LENGTH, "can't get %s's length", mus_name(gen)));
  499. }
  500. mus_long_t mus_set_length(mus_any *gen, mus_long_t len)
  501. {
  502. if ((check_gen(gen, S_set S_mus_length)) &&
  503. (gen->core->set_length))
  504. return((*(gen->core->set_length))(gen, len));
  505. return(mus_error(MUS_NO_LENGTH, "can't set %s's length", mus_name(gen)));
  506. }
  507. mus_long_t mus_order(mus_any *gen) /* shares "length", no set */
  508. {
  509. if ((check_gen(gen, S_mus_order)) &&
  510. (gen->core->length))
  511. return((*(gen->core->length))(gen));
  512. return(mus_error(MUS_NO_ORDER, "can't get %s's order", mus_name(gen)));
  513. }
  514. int mus_channels(mus_any *gen)
  515. {
  516. if ((check_gen(gen, S_mus_channels)) &&
  517. (gen->core->channels))
  518. return((*(gen->core->channels))(gen));
  519. return(mus_error(MUS_NO_CHANNELS, "can't get %s's channels", mus_name(gen)));
  520. }
  521. int mus_interp_type(mus_any *gen) /* shares "channels", no set */
  522. {
  523. if ((check_gen(gen, S_mus_interp_type)) &&
  524. (gen->core->channels))
  525. return((*(gen->core->channels))(gen));
  526. return(mus_error(MUS_NO_INTERP_TYPE, "can't get %s's interp type", mus_name(gen)));
  527. }
  528. int mus_position(mus_any *gen) /* shares "channels", no set, only used in C (snd-env.c) */
  529. {
  530. if ((check_gen(gen, "mus-position")) &&
  531. (gen->core->channels))
  532. return((*(gen->core->channels))(gen));
  533. return(mus_error(MUS_NO_POSITION, "can't get %s's position", mus_name(gen)));
  534. }
  535. int mus_channel(mus_any *gen)
  536. {
  537. if ((check_gen(gen, S_mus_channel)) &&
  538. (gen->core->channel))
  539. return(((*gen->core->channel))(gen));
  540. return(mus_error(MUS_NO_CHANNEL, "can't get %s's channel", mus_name(gen)));
  541. }
  542. mus_long_t mus_hop(mus_any *gen)
  543. {
  544. if ((check_gen(gen, S_mus_hop)) &&
  545. (gen->core->hop))
  546. return((*(gen->core->hop))(gen));
  547. return(mus_error(MUS_NO_HOP, "can't get %s's hop value", mus_name(gen)));
  548. }
  549. mus_long_t mus_set_hop(mus_any *gen, mus_long_t len)
  550. {
  551. if ((check_gen(gen, S_set S_mus_hop)) &&
  552. (gen->core->set_hop))
  553. return((*(gen->core->set_hop))(gen, len));
  554. return(mus_error(MUS_NO_HOP, "can't set %s's hop value", mus_name(gen)));
  555. }
  556. mus_long_t mus_ramp(mus_any *gen)
  557. {
  558. if ((check_gen(gen, S_mus_ramp)) &&
  559. (gen->core->ramp))
  560. return((*(gen->core->ramp))(gen));
  561. return(mus_error(MUS_NO_RAMP, "can't get %s's ramp value", mus_name(gen)));
  562. }
  563. mus_long_t mus_set_ramp(mus_any *gen, mus_long_t len)
  564. {
  565. if ((check_gen(gen, S_set S_mus_ramp)) &&
  566. (gen->core->set_ramp))
  567. return((*(gen->core->set_ramp))(gen, len));
  568. return(mus_error(MUS_NO_RAMP, "can't set %s's ramp value", mus_name(gen)));
  569. }
  570. mus_float_t *mus_data(mus_any *gen)
  571. {
  572. if ((check_gen(gen, S_mus_data)) &&
  573. (gen->core->data))
  574. return((*(gen->core->data))(gen));
  575. mus_error(MUS_NO_DATA, "can't get %s's data", mus_name(gen));
  576. return(NULL);
  577. }
  578. /* every case that implements the data or set data functions needs to include
  579. * a var-allocated flag, since all such memory has to be handled via vcts
  580. */
  581. mus_float_t *mus_set_data(mus_any *gen, mus_float_t *new_data)
  582. {
  583. if (check_gen(gen, S_set S_mus_data))
  584. {
  585. if (gen->core->set_data)
  586. {
  587. (*(gen->core->set_data))(gen, new_data);
  588. return(new_data);
  589. }
  590. else mus_error(MUS_NO_DATA, "can't set %s's data", mus_name(gen));
  591. }
  592. return(new_data);
  593. }
  594. mus_float_t *mus_xcoeffs(mus_any *gen)
  595. {
  596. if ((check_gen(gen, S_mus_xcoeffs)) &&
  597. (gen->core->xcoeffs))
  598. return((*(gen->core->xcoeffs))(gen));
  599. mus_error(MUS_NO_XCOEFFS, "can't get %s's xcoeffs", mus_name(gen));
  600. return(NULL);
  601. }
  602. mus_float_t *mus_ycoeffs(mus_any *gen)
  603. {
  604. if ((check_gen(gen, S_mus_ycoeffs)) &&
  605. (gen->core->ycoeffs))
  606. return((*(gen->core->ycoeffs))(gen));
  607. mus_error(MUS_NO_YCOEFFS, "can't get %s's ycoeffs", mus_name(gen));
  608. return(NULL);
  609. }
  610. mus_float_t mus_xcoeff(mus_any *gen, int index)
  611. {
  612. if ((check_gen(gen, S_mus_xcoeff)) &&
  613. (gen->core->xcoeff))
  614. return((*(gen->core->xcoeff))(gen, index));
  615. return(mus_error(MUS_NO_XCOEFF, "can't get %s's xcoeff[%d] value", mus_name(gen), index));
  616. }
  617. mus_float_t mus_set_xcoeff(mus_any *gen, int index, mus_float_t val)
  618. {
  619. if ((check_gen(gen, S_set S_mus_xcoeff)) &&
  620. (gen->core->set_xcoeff))
  621. return((*(gen->core->set_xcoeff))(gen, index, val));
  622. return(mus_error(MUS_NO_XCOEFF, "can't set %s's xcoeff[%d] value", mus_name(gen), index));
  623. }
  624. mus_float_t mus_ycoeff(mus_any *gen, int index)
  625. {
  626. if ((check_gen(gen, S_mus_ycoeff)) &&
  627. (gen->core->ycoeff))
  628. return((*(gen->core->ycoeff))(gen, index));
  629. return(mus_error(MUS_NO_YCOEFF, "can't get %s's ycoeff[%d] value", mus_name(gen), index));
  630. }
  631. mus_float_t mus_set_ycoeff(mus_any *gen, int index, mus_float_t val)
  632. {
  633. if ((check_gen(gen, S_set S_mus_ycoeff)) &&
  634. (gen->core->set_ycoeff))
  635. return((*(gen->core->set_ycoeff))(gen, index, val));
  636. return(mus_error(MUS_NO_YCOEFF, "can't set %s's ycoeff[%d] value", mus_name(gen), index));
  637. }
  638. mus_long_t mus_location(mus_any *gen)
  639. {
  640. if ((check_gen(gen, S_mus_location)) &&
  641. (gen->core->location))
  642. return(((*gen->core->location))(gen));
  643. return((mus_long_t)mus_error(MUS_NO_LOCATION, "can't get %s's location", mus_name(gen)));
  644. }
  645. /* ---------------- AM etc ---------------- */
  646. mus_float_t mus_ring_modulate(mus_float_t sig1, mus_float_t sig2)
  647. {
  648. return(sig1 * sig2);
  649. }
  650. mus_float_t mus_amplitude_modulate(mus_float_t carrier, mus_float_t sig1, mus_float_t sig2)
  651. {
  652. return(sig1 * (carrier + sig2));
  653. }
  654. mus_float_t mus_contrast_enhancement(mus_float_t sig, mus_float_t index)
  655. {
  656. return(sin((sig * M_PI_2) + (index * sin(sig * TWO_PI))));
  657. }
  658. bool mus_arrays_are_equal(mus_float_t *arr1, mus_float_t *arr2, mus_float_t fudge, mus_long_t len)
  659. {
  660. mus_long_t i;
  661. if (fudge == 0.0)
  662. {
  663. for (i = 0; i < len; i++)
  664. if (arr1[i] != arr2[i])
  665. return(false);
  666. }
  667. else
  668. {
  669. mus_long_t len4;
  670. len4 = len - 4;
  671. i = 0;
  672. while (i <= len4)
  673. {
  674. if (fabs(arr1[i] - arr2[i]) > fudge)
  675. return(false);
  676. i++;
  677. if (fabs(arr1[i] - arr2[i]) > fudge)
  678. return(false);
  679. i++;
  680. if (fabs(arr1[i] - arr2[i]) > fudge)
  681. return(false);
  682. i++;
  683. if (fabs(arr1[i] - arr2[i]) > fudge)
  684. return(false);
  685. i++;
  686. }
  687. for (; i < len; i++)
  688. if (fabs(arr1[i] - arr2[i]) > fudge)
  689. return(false);
  690. }
  691. return(true);
  692. }
  693. static bool clm_arrays_are_equal(mus_float_t *arr1, mus_float_t *arr2, mus_long_t len)
  694. {
  695. return(mus_arrays_are_equal(arr1, arr2, float_equal_fudge_factor, len));
  696. }
  697. mus_float_t mus_dot_product(mus_float_t *data1, mus_float_t *data2, mus_long_t size)
  698. {
  699. mus_long_t i, size4;
  700. mus_float_t sum = 0.0;
  701. size4 = size - 4;
  702. i = 0;
  703. while (i <= size4)
  704. {
  705. sum += (data1[i] * data2[i]);
  706. i++;
  707. sum += (data1[i] * data2[i]);
  708. i++;
  709. sum += (data1[i] * data2[i]);
  710. i++;
  711. sum += (data1[i] * data2[i]);
  712. i++;
  713. }
  714. for (; i < size; i++)
  715. sum += (data1[i] * data2[i]);
  716. return(sum);
  717. }
  718. #if HAVE_COMPLEX_TRIG
  719. #if HAVE_FORTH
  720. #include "xen.h"
  721. #endif
  722. complex double mus_edot_product(complex double freq, complex double *data, mus_long_t size)
  723. {
  724. int i;
  725. complex double sum = 0.0;
  726. for (i = 0; i < size; i++)
  727. sum += (cexp(i * freq) * data[i]);
  728. return(sum);
  729. }
  730. #endif
  731. mus_float_t mus_polynomial(mus_float_t *coeffs, mus_float_t x, int ncoeffs)
  732. {
  733. mus_float_t sum;
  734. int i;
  735. if (ncoeffs <= 0) return(0.0);
  736. if (ncoeffs == 1) return(coeffs[0]); /* just a constant term */
  737. sum = coeffs[ncoeffs - 1];
  738. /* unrolled is slower */
  739. for (i = ncoeffs - 2; i >= 0; i--)
  740. sum = (sum * x) + coeffs[i];
  741. return((mus_float_t)sum);
  742. }
  743. void mus_rectangular_to_polar(mus_float_t *rl, mus_float_t *im, mus_long_t size)
  744. {
  745. mus_long_t i;
  746. for (i = 0; i < size; i++)
  747. {
  748. mus_float_t temp; /* apparently floating underflows (denormals?) in sqrt are bringing us to a halt */
  749. temp = rl[i] * rl[i] + im[i] * im[i];
  750. if (temp < .00000001)
  751. {
  752. rl[i] = 0.0;
  753. im[i] = 0.0;
  754. }
  755. else
  756. {
  757. im[i] = -atan2(im[i], rl[i]); /* "-" here so that clockwise is positive? is this backwards? */
  758. rl[i] = sqrt(temp);
  759. }
  760. }
  761. }
  762. void mus_rectangular_to_magnitudes(mus_float_t *rl, mus_float_t *im, mus_long_t size)
  763. {
  764. mus_long_t i;
  765. for (i = 0; i < size; i++)
  766. {
  767. mus_float_t temp; /* apparently floating underflows in sqrt are bringing us to a halt */
  768. temp = rl[i] * rl[i] + im[i] * im[i];
  769. if (temp < .00000001)
  770. rl[i] = 0.0;
  771. else rl[i] = sqrt(temp);
  772. }
  773. }
  774. void mus_polar_to_rectangular(mus_float_t *rl, mus_float_t *im, mus_long_t size)
  775. {
  776. mus_long_t i;
  777. for (i = 0; i < size; i++)
  778. {
  779. #if HAVE_SINCOS
  780. double sx, cx;
  781. sincos(-im[i], &sx, &cx);
  782. im[i] = sx * rl[i];
  783. rl[i] *= cx;
  784. #else
  785. mus_float_t temp;
  786. temp = rl[i] * sin(-im[i]); /* minus to match sense of rectangular->polar above */
  787. rl[i] *= cos(-im[i]);
  788. im[i] = temp;
  789. #endif
  790. }
  791. }
  792. static mus_float_t *array_normalize(mus_float_t *table, mus_long_t table_size)
  793. {
  794. mus_float_t amp = 0.0;
  795. mus_long_t i;
  796. for (i = 0; i < table_size; i++)
  797. if (amp < (fabs(table[i])))
  798. amp = fabs(table[i]);
  799. if ((amp > 0.0) &&
  800. (amp != 1.0))
  801. for (i = 0; i < table_size; i++)
  802. table[i] /= amp;
  803. return(table);
  804. }
  805. /* ---------------- interpolation ---------------- */
  806. mus_float_t mus_array_interp(mus_float_t *wave, mus_float_t phase, mus_long_t size)
  807. {
  808. /* changed 26-Sep-00 to be closer to mus.lisp */
  809. mus_long_t int_part;
  810. mus_float_t frac_part;
  811. if ((phase < 0.0) || (phase > size))
  812. {
  813. /* 28-Mar-01 changed to fmod; I was hoping to avoid this... */
  814. phase = fmod((mus_float_t)phase, (mus_float_t)size);
  815. if (phase < 0.0) phase += size;
  816. }
  817. int_part = (mus_long_t)phase; /* (mus_long_t)floor(phase); */
  818. frac_part = phase - int_part;
  819. if (int_part == size) int_part = 0;
  820. if (frac_part == 0.0)
  821. return(wave[int_part]);
  822. else
  823. {
  824. mus_long_t inx;
  825. inx = int_part + 1;
  826. if (inx >= size) inx = 0;
  827. return(wave[int_part] + (frac_part * (wave[inx] - wave[int_part])));
  828. }
  829. }
  830. static mus_float_t mus_array_all_pass_interp(mus_float_t *wave, mus_float_t phase, mus_long_t size, mus_float_t yn1)
  831. {
  832. /* this is intended for delay lines where you have a stream of values; in table-lookup it can be a mess */
  833. mus_long_t int_part, inx;
  834. mus_float_t frac_part;
  835. if ((phase < 0.0) || (phase > size))
  836. {
  837. phase = fmod((mus_float_t)phase, (mus_float_t)size);
  838. if (phase < 0.0) phase += size;
  839. }
  840. int_part = (mus_long_t)floor(phase);
  841. frac_part = phase - int_part;
  842. if (int_part == size) int_part = 0;
  843. inx = int_part + 1;
  844. if (inx >= size) inx -= size;
  845. #if 1
  846. /* from DAFX */
  847. if (frac_part == 0.0)
  848. return(wave[inx] - yn1);
  849. return(wave[int_part] * frac_part + (1.0 - frac_part) * (wave[inx] - yn1));
  850. #else
  851. /* from Perry Cook */
  852. if (frac_part == 0.0)
  853. return(wave[int_part] + wave[inx] - yn1);
  854. else return(wave[int_part] + ((1.0 - frac_part) / (1 + frac_part)) * (wave[inx] - yn1));
  855. #endif
  856. }
  857. static mus_float_t mus_array_lagrange_interp(mus_float_t *wave, mus_float_t x, mus_long_t size)
  858. {
  859. /* Abramovitz and Stegun 25.2.11 -- everyone badmouths this poor formula */
  860. /* x assumed to be in the middle, between second and third vals */
  861. mus_long_t x0, xp1, xm1;
  862. mus_float_t p, pp;
  863. if ((x < 0.0) || (x > size))
  864. {
  865. x = fmod((mus_float_t)x, (mus_float_t)size);
  866. if (x < 0.0) x += size;
  867. }
  868. x0 = (mus_long_t)floor(x);
  869. p = x - x0;
  870. if (x0 >= size) x0 -= size;
  871. if (p == 0.0) return(wave[x0]);
  872. xp1 = x0 + 1;
  873. if (xp1 >= size) xp1 -= size;
  874. xm1 = x0 - 1;
  875. if (xm1 < 0) xm1 += size;
  876. pp = p * p;
  877. return((wave[xm1] * 0.5 * (pp - p)) +
  878. (wave[x0] * (1.0 - pp)) +
  879. (wave[xp1] * 0.5 * (p + pp)));
  880. }
  881. static mus_float_t mus_array_hermite_interp(mus_float_t *wave, mus_float_t x, mus_long_t size)
  882. {
  883. /* from James McCartney */
  884. mus_long_t x0, x1, x2, x3;
  885. mus_float_t p, c0, c1, c2, c3, y0, y1, y2, y3;
  886. if ((x < 0.0) || (x > size))
  887. {
  888. x = fmod((mus_float_t)x, (mus_float_t)size);
  889. if (x < 0.0) x += size;
  890. }
  891. x1 = (mus_long_t)floor(x);
  892. p = x - x1;
  893. if (x1 == size) x1 = 0;
  894. if (p == 0.0) return(wave[x1]);
  895. x2 = x1 + 1;
  896. if (x2 == size) x2 = 0;
  897. x3 = x2 + 1;
  898. if (x3 == size) x3 = 0;
  899. x0 = x1 - 1;
  900. if (x0 < 0) x0 = size - 1;
  901. y0 = wave[x0];
  902. y1 = wave[x1];
  903. y2 = wave[x2];
  904. y3 = wave[x3];
  905. c0 = y1;
  906. c1 = 0.5 * (y2 - y0);
  907. c3 = 1.5 * (y1 - y2) + 0.5 * (y3 - y0);
  908. c2 = y0 - y1 + c1 - c3;
  909. return(((c3 * p + c2) * p + c1) * p + c0);
  910. }
  911. static mus_float_t mus_array_bezier_interp(mus_float_t *wave, mus_float_t x, mus_long_t size)
  912. {
  913. mus_long_t x0, x1, x2, x3;
  914. mus_float_t p, y0, y1, y2, y3, ay, by, cy;
  915. if ((x < 0.0) || (x > size))
  916. {
  917. x = fmod((mus_float_t)x, (mus_float_t)size);
  918. if (x < 0.0) x += size;
  919. }
  920. x1 = (mus_long_t)floor(x);
  921. p = ((x - x1) + 1.0) / 3.0;
  922. if (x1 == size) x1 = 0;
  923. x2 = x1 + 1;
  924. if (x2 == size) x2 = 0;
  925. x3 = x2 + 1;
  926. if (x3 == size) x3 = 0;
  927. x0 = x1 - 1;
  928. if (x0 < 0) x0 = size - 1;
  929. y0 = wave[x0];
  930. y1 = wave[x1];
  931. y2 = wave[x2];
  932. y3 = wave[x3];
  933. cy = 3 * (y1 - y0);
  934. by = 3 * (y2 - y1) - cy;
  935. ay = y3 - y0 - cy - by;
  936. return(y0 + p * (cy + (p * (by + (p * ay)))));
  937. }
  938. bool mus_is_interp_type(int val)
  939. {
  940. /* this is C++'s fault. */
  941. switch (val)
  942. {
  943. case MUS_INTERP_NONE:
  944. case MUS_INTERP_LINEAR:
  945. case MUS_INTERP_SINUSOIDAL:
  946. case MUS_INTERP_LAGRANGE:
  947. case MUS_INTERP_HERMITE:
  948. case MUS_INTERP_ALL_PASS:
  949. case MUS_INTERP_BEZIER:
  950. return(true);
  951. break;
  952. }
  953. return(false);
  954. }
  955. mus_float_t mus_interpolate(mus_interp_t type, mus_float_t x, mus_float_t *table, mus_long_t table_size, mus_float_t y)
  956. {
  957. switch (type)
  958. {
  959. case MUS_INTERP_NONE:
  960. {
  961. mus_long_t x0;
  962. x0 = ((mus_long_t)x) % table_size;
  963. if (x0 < 0) x0 += table_size;
  964. return(table[x0]);
  965. }
  966. break;
  967. case MUS_INTERP_LAGRANGE:
  968. return(mus_array_lagrange_interp(table, x, table_size));
  969. break;
  970. case MUS_INTERP_HERMITE:
  971. return(mus_array_hermite_interp(table, x, table_size));
  972. break;
  973. case MUS_INTERP_LINEAR:
  974. return(mus_array_interp(table, x, table_size));
  975. break;
  976. case MUS_INTERP_ALL_PASS:
  977. return(mus_array_all_pass_interp(table, x, table_size, y));
  978. break;
  979. case MUS_INTERP_BEZIER:
  980. return(mus_array_bezier_interp(table, x, table_size));
  981. break;
  982. default:
  983. mus_error(MUS_ARG_OUT_OF_RANGE, "unknown interpolation type: %d", type);
  984. break;
  985. }
  986. return(0.0);
  987. }
  988. /* ---------------- oscil ---------------- */
  989. typedef struct {
  990. mus_any_class *core;
  991. mus_float_t phase, freq;
  992. } osc;
  993. mus_float_t mus_oscil(mus_any *ptr, mus_float_t fm, mus_float_t pm)
  994. {
  995. osc *gen = (osc *)ptr;
  996. mus_float_t result;
  997. result = gen->phase + pm;
  998. gen->phase += (gen->freq + fm);
  999. return(sin(result));
  1000. }
  1001. mus_float_t mus_oscil_unmodulated(mus_any *ptr)
  1002. {
  1003. osc *gen = (osc *)ptr;
  1004. mus_float_t result;
  1005. result = gen->phase;
  1006. gen->phase += gen->freq;
  1007. return(sin(result));
  1008. }
  1009. mus_float_t mus_oscil_fm(mus_any *ptr, mus_float_t fm)
  1010. {
  1011. osc *gen = (osc *)ptr;
  1012. mus_float_t result;
  1013. result = gen->phase;
  1014. gen->phase += (gen->freq + fm);
  1015. return(sin(result));
  1016. }
  1017. mus_float_t mus_oscil_pm(mus_any *ptr, mus_float_t pm)
  1018. {
  1019. mus_float_t result;
  1020. osc *gen = (osc *)ptr;
  1021. result = gen->phase + pm;
  1022. gen->phase += gen->freq;
  1023. return(sin(result));
  1024. }
  1025. bool mus_is_oscil(mus_any *ptr)
  1026. {
  1027. return((ptr) &&
  1028. (ptr->core->type == MUS_OSCIL));
  1029. }
  1030. /* this could be: bool mus_is_oscil(mus_any *ptr) {return((ptr) && (ptr->core == &OSCIL_CLASS));}
  1031. */
  1032. static void free_oscil(mus_any *ptr) {free(ptr);}
  1033. static mus_float_t oscil_freq(mus_any *ptr) {return(mus_radians_to_hz(((osc *)ptr)->freq));}
  1034. static mus_float_t oscil_set_freq(mus_any *ptr, mus_float_t val) {((osc *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  1035. static mus_float_t oscil_increment(mus_any *ptr) {return(((osc *)ptr)->freq);}
  1036. static mus_float_t oscil_set_increment(mus_any *ptr, mus_float_t val) {((osc *)ptr)->freq = val; return(val);}
  1037. static mus_float_t oscil_phase(mus_any *ptr) {return(fmod(((osc *)ptr)->phase, TWO_PI));}
  1038. static mus_float_t oscil_set_phase(mus_any *ptr, mus_float_t val) {((osc *)ptr)->phase = val; return(val);}
  1039. static mus_long_t oscil_cosines(mus_any *ptr) {return(1);}
  1040. static void oscil_reset(mus_any *ptr) {((osc *)ptr)->phase = 0.0;}
  1041. static mus_any *oscil_copy(mus_any *ptr)
  1042. {
  1043. osc *g;
  1044. g = (osc *)malloc(sizeof(osc));
  1045. memcpy((void *)g, (void *)ptr, sizeof(osc));
  1046. return((mus_any *)g);
  1047. }
  1048. static mus_float_t fallback_scaler(mus_any *ptr) {return(1.0);}
  1049. static bool oscil_equalp(mus_any *p1, mus_any *p2)
  1050. {
  1051. return((p1 == p2) ||
  1052. ((mus_is_oscil((mus_any *)p1)) &&
  1053. (mus_is_oscil((mus_any *)p2)) &&
  1054. ((((osc *)p1)->freq) == (((osc *)p2)->freq)) &&
  1055. ((((osc *)p1)->phase) == (((osc *)p2)->phase))));
  1056. }
  1057. static char *describe_oscil(mus_any *ptr)
  1058. {
  1059. char *describe_buffer;
  1060. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1061. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f",
  1062. mus_name(ptr),
  1063. mus_frequency(ptr),
  1064. mus_phase(ptr));
  1065. return(describe_buffer);
  1066. }
  1067. static mus_any_class OSCIL_CLASS = {
  1068. MUS_OSCIL,
  1069. (char *)S_oscil, /* the "(char *)" business is for g++'s benefit */
  1070. &free_oscil,
  1071. &describe_oscil,
  1072. &oscil_equalp,
  1073. 0, 0,
  1074. &oscil_cosines, 0,
  1075. &oscil_freq,
  1076. &oscil_set_freq,
  1077. &oscil_phase,
  1078. &oscil_set_phase,
  1079. &fallback_scaler, 0,
  1080. &oscil_increment,
  1081. &oscil_set_increment,
  1082. &mus_oscil,
  1083. MUS_NOT_SPECIAL,
  1084. NULL,
  1085. 0,
  1086. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1087. 0, 0, 0, 0, 0, 0, 0,
  1088. 0, 0, 0, 0,
  1089. &oscil_reset,
  1090. 0,
  1091. &oscil_copy
  1092. };
  1093. mus_any *mus_make_oscil(mus_float_t freq, mus_float_t phase)
  1094. {
  1095. osc *gen;
  1096. gen = (osc *)malloc(sizeof(osc));
  1097. gen->core = &OSCIL_CLASS;
  1098. gen->freq = mus_hz_to_radians(freq);
  1099. gen->phase = phase;
  1100. return((mus_any *)gen);
  1101. }
  1102. /* decided against feedback-oscil (as in cellon) because it's not clear how to handle the index,
  1103. * and there are many options for the filtering -- since this part of the signal path
  1104. * is not hidden, there's no reason to bring it out explicitly (as in filtered-comb)
  1105. */
  1106. /* ---------------- oscil-bank ---------------- */
  1107. typedef struct {
  1108. mus_any_class *core;
  1109. int size, orig_size;
  1110. mus_float_t *amps, *phases, *freqs; /* these can change, so sincos is not always safe */
  1111. bool free_phases;
  1112. mus_float_t (*ob_func)(mus_any *ptr);
  1113. #if HAVE_SINCOS
  1114. double *sn1, *cs1, *sn2, *cs2, *phs;
  1115. bool use_sc;
  1116. #endif
  1117. } ob;
  1118. static void free_oscil_bank(mus_any *ptr)
  1119. {
  1120. ob *g = (ob *)ptr;
  1121. #if HAVE_SINCOS
  1122. if (g->sn1) {free(g->sn1); g->sn1 = NULL;}
  1123. if (g->sn2) {free(g->sn2); g->sn2 = NULL;}
  1124. if (g->cs1) {free(g->cs1); g->cs1 = NULL;}
  1125. if (g->cs2) {free(g->cs2); g->cs2 = NULL;}
  1126. if (g->phs) {free(g->phs); g->phs = NULL;}
  1127. #endif
  1128. if ((g->phases) && (g->free_phases)) {free(g->phases); g->phases = NULL;}
  1129. free(ptr);
  1130. }
  1131. static mus_any *ob_copy(mus_any *ptr)
  1132. {
  1133. ob *g, *p;
  1134. int bytes;
  1135. p = (ob *)ptr;
  1136. g = (ob *)malloc(sizeof(ob));
  1137. memcpy((void *)g, (void *)ptr, sizeof(ob));
  1138. g->ob_func = p->ob_func;
  1139. #if HAVE_SINCOS
  1140. if (g->sn1)
  1141. {
  1142. bytes = g->size * sizeof(double);
  1143. g->sn1 = (double *)malloc(bytes);
  1144. memcpy((void *)(g->sn1), (void *)(p->sn1), bytes);
  1145. g->sn2 = (double *)malloc(bytes);
  1146. memcpy((void *)(g->sn2), (void *)(p->sn2), bytes);
  1147. g->cs1 = (double *)malloc(bytes);
  1148. memcpy((void *)(g->cs1), (void *)(p->cs1), bytes);
  1149. g->cs2 = (double *)malloc(bytes);
  1150. memcpy((void *)(g->cs2), (void *)(p->cs2), bytes);
  1151. g->phs = (double *)malloc(bytes);
  1152. memcpy((void *)(g->phs), (void *)(p->phs), bytes);
  1153. g->use_sc = p->use_sc;
  1154. }
  1155. #endif
  1156. bytes = g->size * sizeof(mus_float_t);
  1157. /* we have to make a new phases array -- otherwise the original and copy step on each other */
  1158. g->free_phases = true;
  1159. g->phases = (mus_float_t *)malloc(bytes);
  1160. memcpy((void *)(g->phases), (void *)(p->phases), bytes);
  1161. return((mus_any *)g);
  1162. }
  1163. static mus_float_t *ob_data(mus_any *ptr) {return(((ob *)ptr)->phases);}
  1164. static mus_float_t run_oscil_bank(mus_any *ptr, mus_float_t input, mus_float_t unused)
  1165. {
  1166. return(mus_oscil_bank(ptr));
  1167. }
  1168. static mus_long_t oscil_bank_length(mus_any *ptr)
  1169. {
  1170. return(((ob *)ptr)->size);
  1171. }
  1172. static mus_long_t oscil_bank_set_length(mus_any *ptr, mus_long_t len)
  1173. {
  1174. ob *g = (ob *)ptr;
  1175. if (len < 0)
  1176. g->size = 0;
  1177. else
  1178. {
  1179. if (len > g->orig_size)
  1180. g->size = g->orig_size;
  1181. else g->size = len;
  1182. }
  1183. return(len);
  1184. }
  1185. static void oscil_bank_reset(mus_any *ptr)
  1186. {
  1187. ob *p = (ob *)ptr;
  1188. p->size = p->orig_size;
  1189. memset((void *)(p->phases), 0, p->orig_size * sizeof(mus_float_t));
  1190. }
  1191. static bool oscil_bank_equalp(mus_any *p1, mus_any *p2)
  1192. {
  1193. ob *o1 = (ob *)p1;
  1194. ob *o2 = (ob *)p2;
  1195. if (p1 == p2) return(true);
  1196. return((o1->size == o2->size) &&
  1197. (o1->orig_size == o2->orig_size) &&
  1198. (o1->amps == o2->amps) &&
  1199. (o1->freqs == o2->freqs) &&
  1200. ((o1->phases == o2->phases) ||
  1201. (clm_arrays_are_equal(o1->phases, o2->phases, o2->size))));
  1202. }
  1203. static char *describe_oscil_bank(mus_any *ptr)
  1204. {
  1205. ob *gen = (ob *)ptr;
  1206. char *describe_buffer;
  1207. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1208. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d",
  1209. mus_name(ptr),
  1210. gen->size);
  1211. return(describe_buffer);
  1212. }
  1213. static mus_any_class OSCIL_BANK_CLASS = {
  1214. MUS_OSCIL_BANK,
  1215. (char *)S_oscil_bank,
  1216. &free_oscil_bank,
  1217. &describe_oscil_bank,
  1218. &oscil_bank_equalp,
  1219. &ob_data, 0,
  1220. &oscil_bank_length, &oscil_bank_set_length,
  1221. 0, 0,
  1222. 0, 0,
  1223. 0, 0,
  1224. 0, 0,
  1225. &run_oscil_bank,
  1226. MUS_NOT_SPECIAL,
  1227. NULL, 0,
  1228. 0, 0, 0, 0,
  1229. 0, 0,
  1230. 0, 0, 0, 0,
  1231. 0, 0, 0, 0, 0, 0, 0,
  1232. 0, 0, 0, 0,
  1233. &oscil_bank_reset,
  1234. 0, &ob_copy
  1235. };
  1236. bool mus_is_oscil_bank(mus_any *ptr)
  1237. {
  1238. return((ptr) &&
  1239. (ptr->core->type == MUS_OSCIL_BANK));
  1240. }
  1241. static mus_float_t oscil_bank(mus_any *ptr)
  1242. {
  1243. ob *p = (ob *)ptr;
  1244. int i;
  1245. mus_float_t sum = 0.0;
  1246. if (!p->amps)
  1247. {
  1248. for (i = 0; i < p->size; i++)
  1249. {
  1250. sum += sin(p->phases[i]);
  1251. p->phases[i] += p->freqs[i];
  1252. }
  1253. }
  1254. else
  1255. {
  1256. for (i = 0; i < p->size; i++)
  1257. {
  1258. sum += (p->amps[i] * sin(p->phases[i]));
  1259. p->phases[i] += p->freqs[i];
  1260. }
  1261. }
  1262. return(sum);
  1263. }
  1264. #if HAVE_SINCOS
  1265. static mus_float_t stable_oscil_bank(mus_any *ptr)
  1266. {
  1267. ob *p = (ob *)ptr;
  1268. int i;
  1269. mus_float_t sum = 0.0;
  1270. if (p->use_sc)
  1271. {
  1272. for (i = 0; i < p->size; i++)
  1273. sum += (p->sn1[i] * p->cs2[i] + p->cs1[i] * p->sn2[i]);
  1274. p->use_sc = false;
  1275. }
  1276. else
  1277. {
  1278. double s, c;
  1279. if (!p->amps)
  1280. {
  1281. for (i = 0; i < p->size; i++)
  1282. {
  1283. sincos(p->phases[i], &s, &c);
  1284. p->sn2[i] = s;
  1285. p->cs2[i] = c;
  1286. sum += s;
  1287. p->phases[i] += p->phs[i];
  1288. }
  1289. }
  1290. else
  1291. {
  1292. for (i = 0; i < p->size; i++)
  1293. {
  1294. sincos(p->phases[i], &s, &c);
  1295. p->sn2[i] = s;
  1296. p->cs2[i] = c;
  1297. sum += p->amps[i] * s;
  1298. p->phases[i] += p->phs[i];
  1299. }
  1300. }
  1301. p->use_sc = true;
  1302. }
  1303. return(sum);
  1304. }
  1305. #endif
  1306. mus_float_t mus_oscil_bank(mus_any *ptr)
  1307. {
  1308. ob *p = (ob *)ptr;
  1309. return(p->ob_func(ptr));
  1310. }
  1311. mus_any *mus_make_oscil_bank(int size, mus_float_t *freqs, mus_float_t *phases, mus_float_t *amps, bool stable)
  1312. {
  1313. ob *gen;
  1314. gen = (ob *)malloc(sizeof(ob));
  1315. gen->core = &OSCIL_BANK_CLASS;
  1316. gen->orig_size = size;
  1317. gen->size = size;
  1318. gen->amps = amps;
  1319. gen->freqs = freqs;
  1320. gen->phases = phases;
  1321. gen->free_phases = false;
  1322. gen->ob_func = oscil_bank;
  1323. #if HAVE_SINCOS
  1324. if (stable)
  1325. {
  1326. int i;
  1327. double s, c;
  1328. gen->ob_func = stable_oscil_bank;
  1329. gen->use_sc = false;
  1330. gen->sn1 = (double *)malloc(size * sizeof(double));
  1331. gen->sn2 = (double *)malloc(size * sizeof(double));
  1332. gen->cs1 = (double *)malloc(size * sizeof(double));
  1333. gen->cs2 = (double *)malloc(size * sizeof(double));
  1334. gen->phs = (double *)malloc(size * sizeof(double));
  1335. for (i = 0; i < size; i++)
  1336. {
  1337. sincos(freqs[i], &s, &c);
  1338. if (amps)
  1339. {
  1340. s *= amps[i];
  1341. c *= amps[i];
  1342. }
  1343. gen->sn1[i] = s;
  1344. gen->cs1[i] = c;
  1345. gen->phs[i] = freqs[i] * 2.0;
  1346. }
  1347. }
  1348. else
  1349. {
  1350. gen->sn1 = NULL;
  1351. gen->sn2 = NULL;
  1352. gen->cs1 = NULL;
  1353. gen->cs2 = NULL;
  1354. gen->phs = NULL;
  1355. }
  1356. #endif
  1357. return((mus_any *)gen);
  1358. }
  1359. /* ---------------- ncos ---------------- */
  1360. typedef struct {
  1361. mus_any_class *core;
  1362. int n;
  1363. mus_float_t scaler, cos5, phase, freq;
  1364. } cosp;
  1365. #define DIVISOR_NEAR_ZERO(Den) (fabs(Den) < 1.0e-14)
  1366. mus_float_t mus_ncos(mus_any *ptr, mus_float_t fm)
  1367. {
  1368. /* changed 25-Apr-04: use less stupid formula */
  1369. /* (/ (- (/ (sin (* (+ n 0.5) angle)) (* 2 (sin (* 0.5 angle)))) 0.5) n) */
  1370. mus_float_t val, den;
  1371. cosp *gen = (cosp *)ptr;
  1372. den = sin(gen->phase * 0.5);
  1373. if (DIVISOR_NEAR_ZERO(den)) /* see note -- this was den == 0.0 1-Aug-07 */
  1374. /* perhaps use DBL_EPSILON (1.0e-9 I think) */
  1375. val = 1.0;
  1376. else
  1377. {
  1378. val = (gen->scaler * (((sin(gen->phase * gen->cos5)) / (2.0 * den)) - 0.5));
  1379. if (val > 1.0) val = 1.0;
  1380. /* I think this can't happen now that we check den above, but just in case... */
  1381. /* this check is actually incomplete, since we can be much below the correct value also, but the den check should fix those cases too */
  1382. }
  1383. gen->phase += (gen->freq + fm);
  1384. return((mus_float_t)val);
  1385. }
  1386. /* I think we could add ncos_pm via:
  1387. *
  1388. * mus_float_t mus_ncos_pm(mus_any *ptr, mus_float_t fm, mus_float_t pm)
  1389. * {
  1390. * cosp *gen = (cosp *)ptr;
  1391. * mus_float_t result;
  1392. * gen->phase += pm;
  1393. * result = mus_ncos(ptr, fm);
  1394. * gen->phase -= pm;
  1395. * return(result);
  1396. * }
  1397. *
  1398. * and the same trick could add pm to anything:
  1399. *
  1400. * mus_float_t mus_run_with_pm(mus_any *ptr, mus_float_t fm, mus_float_t pm)
  1401. * {
  1402. * mus_float_t result;
  1403. * mus_set_phase(ptr, mus_phase(ptr) + pm);
  1404. * result = mus_run(ptr, fm, 0.0);
  1405. * mus_set_phase (ptr, mus_phase(ptr) - pm);
  1406. * return(result);
  1407. * }
  1408. *
  1409. * fm could also be handled here so the 4 cases become gen, mus_run_with_fm|pm|fm_and_pm(gen)
  1410. * but... this could just as well happen at the extension language level, except that run doesn't expand macros?
  1411. * The problem with differentiating the pm and using the fm arg is that we'd need a closure.
  1412. */
  1413. #if 0
  1414. /* if the current phase is close to 0.0, there were numerical troubles here:
  1415. :(/ (cos (* 1.5 pi 1.0000000000000007)) (cos (* 0.5 pi 1.0000000000000007)))
  1416. -3.21167411694788
  1417. :(/ (cos (* 1.5 pi 1.0000000000000004)) (cos (* 0.5 pi 1.0000000000000004)))
  1418. -2.63292557243357
  1419. :(/ (cos (* 1.5 pi 1.0000000000000002)) (cos (* 0.5 pi 1.0000000000000002)))
  1420. -1.84007079646018
  1421. :(/ (cos (* 1.5 pi 1.0000000000000001)) (cos (* 0.5 pi 1.0000000000000001)))
  1422. -3.0
  1423. :(/ (cos (* 1.5 pi 1.0000000000000008)) (cos (* 0.5 pi 1.0000000000000008)))
  1424. -3.34939116712516
  1425. ;; 16 bits in is probably too much for mus_float_ts
  1426. ;; these numbers can be hit in normal cases:
  1427. (define (ncos-with-inversions n x)
  1428. ;; Andrews Askey Roy 261
  1429. (let* ((num (cos (* x (+ 0.5 n))))
  1430. (den (cos (* x 0.5)))
  1431. (val (/ num den))) ; Chebyshev polynomial of the third kind! (4th uses sin = our current formula)
  1432. (/ (- (if (even? n) val (- val))
  1433. 0.5)
  1434. (+ 1 (* n 2)))))
  1435. (with-sound (:scaled-to 1.0)
  1436. (do ((i 0 (+ i 1))
  1437. (x 0.0 (+ x .01)))
  1438. ((= i 200)) ; glitch at 100 (= 1)
  1439. (outa i (ncos-with-inversions 1 (* pi x)) *output*)))
  1440. */
  1441. #endif
  1442. bool mus_is_ncos(mus_any *ptr)
  1443. {
  1444. return((ptr) &&
  1445. (ptr->core->type == MUS_NCOS));
  1446. }
  1447. static void free_ncos(mus_any *ptr) {free(ptr);}
  1448. static void ncos_reset(mus_any *ptr) {((cosp *)ptr)->phase = 0.0;}
  1449. static mus_float_t ncos_freq(mus_any *ptr) {return(mus_radians_to_hz(((cosp *)ptr)->freq));}
  1450. static mus_float_t ncos_set_freq(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  1451. static mus_float_t ncos_increment(mus_any *ptr) {return(((cosp *)ptr)->freq);}
  1452. static mus_float_t ncos_set_increment(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->freq = val; return(val);}
  1453. static mus_float_t ncos_phase(mus_any *ptr) {return(fmod(((cosp *)ptr)->phase, TWO_PI));}
  1454. static mus_float_t ncos_set_phase(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->phase = val; return(val);}
  1455. static mus_float_t ncos_scaler(mus_any *ptr) {return(((cosp *)ptr)->scaler);}
  1456. static mus_float_t ncos_set_scaler(mus_any *ptr, mus_float_t val) {((cosp *)ptr)->scaler = val; return(val);}
  1457. static mus_long_t ncos_n(mus_any *ptr) {return(((cosp *)ptr)->n);}
  1458. static mus_any *cosp_copy(mus_any *ptr)
  1459. {
  1460. cosp *g;
  1461. g = (cosp *)malloc(sizeof(cosp));
  1462. memcpy((void *)g, (void *)ptr, sizeof(cosp));
  1463. return((mus_any *)g);
  1464. }
  1465. static mus_long_t ncos_set_n(mus_any *ptr, mus_long_t val)
  1466. {
  1467. cosp *gen = (cosp *)ptr;
  1468. if (val > 0)
  1469. {
  1470. gen->n = (int)val;
  1471. gen->cos5 = val + 0.5;
  1472. gen->scaler = 1.0 / (mus_float_t)val;
  1473. }
  1474. return(val);
  1475. }
  1476. static mus_float_t run_ncos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_ncos(ptr, fm));}
  1477. static bool ncos_equalp(mus_any *p1, mus_any *p2)
  1478. {
  1479. return((p1 == p2) ||
  1480. ((mus_is_ncos((mus_any *)p1)) && (mus_is_ncos((mus_any *)p2)) &&
  1481. ((((cosp *)p1)->freq) == (((cosp *)p2)->freq)) &&
  1482. ((((cosp *)p1)->phase) == (((cosp *)p2)->phase)) &&
  1483. ((((cosp *)p1)->n) == (((cosp *)p2)->n)) &&
  1484. ((((cosp *)p1)->scaler) == (((cosp *)p2)->scaler))));
  1485. }
  1486. static char *describe_ncos(mus_any *ptr)
  1487. {
  1488. char *describe_buffer;
  1489. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1490. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, n: %d",
  1491. mus_name(ptr),
  1492. mus_frequency(ptr),
  1493. mus_phase(ptr),
  1494. (int)mus_order(ptr));
  1495. return(describe_buffer);
  1496. }
  1497. static mus_any_class NCOS_CLASS = {
  1498. MUS_NCOS,
  1499. (char *)S_ncos,
  1500. &free_ncos,
  1501. &describe_ncos,
  1502. &ncos_equalp,
  1503. 0, 0, /* data */
  1504. &ncos_n,
  1505. &ncos_set_n,
  1506. &ncos_freq,
  1507. &ncos_set_freq,
  1508. &ncos_phase,
  1509. &ncos_set_phase,
  1510. &ncos_scaler,
  1511. &ncos_set_scaler,
  1512. &ncos_increment,
  1513. &ncos_set_increment,
  1514. &run_ncos,
  1515. MUS_NOT_SPECIAL,
  1516. NULL,
  1517. 0,
  1518. 0, 0, 0, 0, 0, 0,
  1519. 0, 0, 0, 0,
  1520. 0, 0, 0, 0, 0, 0, 0,
  1521. 0, 0, 0, 0,
  1522. &ncos_reset,
  1523. 0,
  1524. &cosp_copy
  1525. };
  1526. mus_any *mus_make_ncos(mus_float_t freq, int n)
  1527. {
  1528. cosp *gen;
  1529. gen = (cosp *)malloc(sizeof(cosp));
  1530. gen->core = &NCOS_CLASS;
  1531. if (n == 0) n = 1;
  1532. gen->scaler = 1.0 / (mus_float_t)n;
  1533. gen->n = n;
  1534. gen->cos5 = n + 0.5;
  1535. gen->freq = mus_hz_to_radians(freq);
  1536. gen->phase = 0.0;
  1537. return((mus_any *)gen);
  1538. }
  1539. /* ---------------- nsin ---------------- */
  1540. static bool nsin_equalp(mus_any *p1, mus_any *p2)
  1541. {
  1542. return((p1 == p2) ||
  1543. ((mus_is_nsin((mus_any *)p1)) && (mus_is_nsin((mus_any *)p2)) &&
  1544. ((((cosp *)p1)->freq) == (((cosp *)p2)->freq)) &&
  1545. ((((cosp *)p1)->phase) == (((cosp *)p2)->phase)) &&
  1546. ((((cosp *)p1)->n) == (((cosp *)p2)->n)) &&
  1547. ((((cosp *)p1)->scaler) == (((cosp *)p2)->scaler))));
  1548. }
  1549. static char *describe_nsin(mus_any *ptr)
  1550. {
  1551. char *describe_buffer;
  1552. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1553. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, n: %d",
  1554. mus_name(ptr),
  1555. mus_frequency(ptr),
  1556. mus_phase(ptr),
  1557. (int)mus_order(ptr));
  1558. return(describe_buffer);
  1559. }
  1560. bool mus_is_nsin(mus_any *ptr)
  1561. {
  1562. return((ptr) &&
  1563. (ptr->core->type == MUS_NSIN));
  1564. }
  1565. #if 0
  1566. /* its simplest to get the maxes by running an example and recording the maxamp, but it also
  1567. * works for small "n" to use the derivative of the sum-of-sines as a Chebyshev polynomial in cos x,
  1568. * find its roots, and plug acos(root) into the original, recording the max:
  1569. *
  1570. (define (smax coeffs)
  1571. (let* ((n (vct-length coeffs))
  1572. (dcos (make-vct n 1.0)))
  1573. (do ((i 0 (+ i 1)))
  1574. ((= i n))
  1575. (vct-set! dcos i (* (+ i 1) (vct-ref coeffs i))))
  1576. (let ((partials ()))
  1577. (do ((i 0 (+ i 1)))
  1578. ((= i n))
  1579. (set! partials (append (list (vct-ref dcos i) (+ i 1)) partials)))
  1580. (let ((Tn (partials->polynomial (reverse partials))))
  1581. (let ((roots (poly-roots Tn)))
  1582. (let ((mx (* -2 n)))
  1583. (for-each
  1584. (lambda (root)
  1585. (let ((acr (acos root))
  1586. (sum 0.0))
  1587. (do ((i 0 (+ i 1)))
  1588. ((= i n))
  1589. (set! sum (+ sum (* (vct-ref coeffs i) (sin (* (+ i 1) acr))))))
  1590. (if (> (abs sum) mx)
  1591. (set! mx (abs sum)))))
  1592. roots)
  1593. mx))))))
  1594. (smax (make-vct n 1.0))
  1595. * but that's too much effort for an initialization function.
  1596. * much faster is this search (it usually hits an answer in 2 or 3 tries):
  1597. *
  1598. (define (find-nsin-max n)
  1599. (define (ns x n)
  1600. (let* ((a2 (/ x 2))
  1601. (den (sin a2)))
  1602. (if (= den 0.0)
  1603. 0.0
  1604. (/ (* (sin (* n a2)) (sin (* (+ n 1) a2))) den))))
  1605. (define (find-mid-max n lo hi)
  1606. (let ((mid (/ (+ lo hi) 2)))
  1607. (let ((ylo (ns lo n))
  1608. (yhi (ns hi n)))
  1609. (if (< (abs (- ylo yhi)) 1e-100)
  1610. (list (ns mid n)
  1611. (rationalize (/ mid pi) 0.0))
  1612. (if (> ylo yhi)
  1613. (find-mid-max n lo mid)
  1614. (find-mid-max n mid hi))))))
  1615. (find-mid-max n 0.0 (/ pi (+ n .5))))
  1616. *
  1617. * the 'mid' point has a surprisingly simple relation to pi:
  1618. *
  1619. * (find-max 100000000000000)
  1620. * 7.24518620297426541161857919764185053934850053037407235e13
  1621. *
  1622. * (find-max 1000000000000000000000000)
  1623. * 7.24518620297422918568756794921595308358209723004380140e23 1/1333333333333333333333334 = .75e-24 -> (3*pi)/(4*n)
  1624. *
  1625. * (find-max 10000000000000000000000000000000000)
  1626. * 7.24518620297422918568756432662285195872681453497436666955413707681801083640192066844820049586929551886747925783e33
  1627. *
  1628. * which is approximately (/ (* 8 (expt (sin (* pi 3/8)) 2)) (* 3 pi)):
  1629. * 7.245186202974229185687564326622851596467504
  1630. *
  1631. * (to get that expression, plug in 3pi/4n, treat (n+1)/n as essentially 1 as n gets very large,
  1632. * treat (sin x) as about x when x is very small, and simplify)
  1633. * so if n>10, we could use (ns (/ (* 3 pi) (* 4 n)) n) without major error
  1634. * It's possible to differentiate the nsin formula:
  1635. *
  1636. * -(cos(x/2)sin(nx/2)sin((n+1)x/2))/(2sin^2(x/2)) + ncos(nx/2)sin((n+1)x/2)/(2sin(x/2)) + (n+1)sin(nx/2)cos((n+1)x/2)/(2sin(x/2))
  1637. *
  1638. * and find the first 0 when n is very large -- it is very close to 3pi/(4*n)
  1639. */
  1640. #endif
  1641. static mus_float_t nsin_ns(mus_float_t x, int n)
  1642. {
  1643. mus_float_t a2, den;
  1644. a2 = x / 2;
  1645. den = sin(a2);
  1646. if (den == 0.0)
  1647. return(0.0);
  1648. return(sin(n * a2) * sin((n + 1) * a2) / den);
  1649. }
  1650. static mus_float_t find_nsin_scaler(int n, mus_float_t lo, mus_float_t hi)
  1651. {
  1652. mus_float_t mid, ylo, yhi;
  1653. mid = (lo + hi) / 2;
  1654. ylo = nsin_ns(lo, n);
  1655. yhi = nsin_ns(hi, n);
  1656. if (fabs(ylo - yhi) < 1e-12)
  1657. return(nsin_ns(mid, n));
  1658. if (ylo > yhi)
  1659. return(find_nsin_scaler(n, lo, mid));
  1660. return(find_nsin_scaler(n, mid, hi));
  1661. }
  1662. static mus_float_t nsin_scaler(int n)
  1663. {
  1664. return(1.0 / find_nsin_scaler(n, 0.0, M_PI / (n + 0.5)));
  1665. }
  1666. static mus_long_t nsin_set_n(mus_any *ptr, mus_long_t val)
  1667. {
  1668. cosp *gen = (cosp *)ptr;
  1669. gen->n = (int)val;
  1670. gen->cos5 = val + 1.0;
  1671. gen->scaler = nsin_scaler((int)val);
  1672. return(val);
  1673. }
  1674. mus_float_t mus_nsin(mus_any *ptr, mus_float_t fm)
  1675. {
  1676. /* (let* ((a2 (* angle 0.5))
  1677. (den (sin a2)))
  1678. (if (= den 0.0)
  1679. 0.0
  1680. (/ (* (sin (* n a2)) (sin (* (+ n 1) a2))) den)))
  1681. */
  1682. #if HAVE_SINCOS
  1683. double val, a2, ns, nc, s, c;
  1684. cosp *gen = (cosp *)ptr;
  1685. a2 = gen->phase * 0.5;
  1686. sincos(a2, &s, &c);
  1687. if (DIVISOR_NEAR_ZERO(s)) /* see note under ncos */
  1688. val = 0.0;
  1689. else
  1690. {
  1691. sincos(gen->n * a2, &ns, &nc);
  1692. val = gen->scaler * ns * (ns * c + nc * s) / s;
  1693. }
  1694. #else
  1695. mus_float_t val, den, a2;
  1696. cosp *gen = (cosp *)ptr;
  1697. a2 = gen->phase * 0.5;
  1698. den = sin(a2);
  1699. if (DIVISOR_NEAR_ZERO(den)) /* see note under ncos */
  1700. val = 0.0;
  1701. else val = gen->scaler * sin(gen->n * a2) * sin(a2 * gen->cos5) / den;
  1702. #endif
  1703. gen->phase += (gen->freq + fm);
  1704. return((mus_float_t)val);
  1705. }
  1706. static mus_float_t run_nsin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nsin(ptr, fm));}
  1707. static mus_any_class NSIN_CLASS = {
  1708. MUS_NSIN,
  1709. (char *)S_nsin,
  1710. &free_ncos,
  1711. &describe_nsin,
  1712. &nsin_equalp,
  1713. 0, 0, /* data */
  1714. &ncos_n,
  1715. &nsin_set_n,
  1716. &ncos_freq,
  1717. &ncos_set_freq,
  1718. &ncos_phase,
  1719. &ncos_set_phase,
  1720. &ncos_scaler,
  1721. &ncos_set_scaler,
  1722. &ncos_increment,
  1723. &ncos_set_increment,
  1724. &run_nsin,
  1725. MUS_NOT_SPECIAL,
  1726. NULL,
  1727. 0,
  1728. 0, 0, 0, 0, 0, 0,
  1729. 0, 0, 0, 0,
  1730. 0, 0, 0, 0, 0, 0, 0,
  1731. 0, 0, 0, 0,
  1732. &ncos_reset,
  1733. 0,
  1734. &cosp_copy
  1735. };
  1736. mus_any *mus_make_nsin(mus_float_t freq, int n)
  1737. {
  1738. cosp *gen;
  1739. gen = (cosp *)mus_make_ncos(freq, n);
  1740. gen->core = &NSIN_CLASS;
  1741. gen->scaler = nsin_scaler(n);
  1742. gen->cos5 = gen->n + 1.0;
  1743. return((mus_any *)gen);
  1744. }
  1745. /* ---------------- asymmetric-fm ---------------- */
  1746. /* changed from sin(sin) to cos(sin) and added amplitude normalization 6-Sep-07 */
  1747. typedef struct {
  1748. mus_any_class *core;
  1749. mus_float_t r;
  1750. mus_float_t freq, phase;
  1751. mus_float_t ratio;
  1752. mus_float_t cosr, sinr;
  1753. mus_float_t one;
  1754. } asyfm;
  1755. static void free_asymmetric_fm(mus_any *ptr) {free(ptr);}
  1756. static void asyfm_reset(mus_any *ptr) {((asyfm *)ptr)->phase = 0.0;}
  1757. static mus_any *asyfm_copy(mus_any *ptr)
  1758. {
  1759. asyfm *g;
  1760. g = (asyfm *)malloc(sizeof(asyfm));
  1761. memcpy((void *)g, (void *)ptr, sizeof(asyfm));
  1762. return((mus_any *)g);
  1763. }
  1764. static mus_float_t asyfm_freq(mus_any *ptr) {return(mus_radians_to_hz(((asyfm *)ptr)->freq));}
  1765. static mus_float_t asyfm_set_freq(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  1766. static mus_float_t asyfm_increment(mus_any *ptr) {return(((asyfm *)ptr)->freq);}
  1767. static mus_float_t asyfm_set_increment(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->freq = val; return(val);}
  1768. static mus_float_t asyfm_phase(mus_any *ptr) {return(fmod(((asyfm *)ptr)->phase, TWO_PI));}
  1769. static mus_float_t asyfm_set_phase(mus_any *ptr, mus_float_t val) {((asyfm *)ptr)->phase = val; return(val);}
  1770. static mus_float_t asyfm_ratio(mus_any *ptr) {return(((asyfm *)ptr)->ratio);}
  1771. static mus_float_t asyfm_r(mus_any *ptr) {return(((asyfm *)ptr)->r);}
  1772. static mus_float_t asyfm_set_r(mus_any *ptr, mus_float_t val)
  1773. {
  1774. asyfm *gen = (asyfm *)ptr;
  1775. if (val != 0.0)
  1776. {
  1777. gen->r = val;
  1778. gen->cosr = 0.5 * (val - (1.0 / val));
  1779. gen->sinr = 0.5 * (val + (1.0 / val));
  1780. if ((val > 1.0) ||
  1781. ((val < 0.0) && (val > -1.0)))
  1782. gen->one = -1.0;
  1783. else gen->one = 1.0;
  1784. }
  1785. return(val);
  1786. }
  1787. static bool asyfm_equalp(mus_any *p1, mus_any *p2)
  1788. {
  1789. return((p1 == p2) ||
  1790. (((p1->core)->type == (p2->core)->type) &&
  1791. ((((asyfm *)p1)->freq) == (((asyfm *)p2)->freq)) &&
  1792. ((((asyfm *)p1)->phase) == (((asyfm *)p2)->phase)) &&
  1793. ((((asyfm *)p1)->ratio) == (((asyfm *)p2)->ratio)) &&
  1794. ((((asyfm *)p1)->r) == (((asyfm *)p2)->r))));
  1795. }
  1796. static char *describe_asyfm(mus_any *ptr)
  1797. {
  1798. char *describe_buffer;
  1799. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1800. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, ratio: %.3f, r: %.3f",
  1801. mus_name(ptr),
  1802. mus_frequency(ptr),
  1803. mus_phase(ptr),
  1804. ((asyfm *)ptr)->ratio,
  1805. asyfm_r(ptr));
  1806. return(describe_buffer);
  1807. }
  1808. bool mus_is_asymmetric_fm(mus_any *ptr)
  1809. {
  1810. return((ptr) &&
  1811. (ptr->core->type == MUS_ASYMMETRIC_FM));
  1812. }
  1813. mus_float_t mus_asymmetric_fm(mus_any *ptr, mus_float_t index, mus_float_t fm)
  1814. {
  1815. asyfm *gen = (asyfm *)ptr;
  1816. mus_float_t result;
  1817. mus_float_t mth;
  1818. mth = gen->ratio * gen->phase;
  1819. result = exp(index * gen->cosr * (gen->one + cos(mth))) * cos(gen->phase + index * gen->sinr * sin(mth));
  1820. /* second index factor added 4-Mar-02 and (+/-)1.0 + cos to normalize amps 6-Sep-07 */
  1821. gen->phase += (gen->freq + fm);
  1822. return(result);
  1823. }
  1824. mus_float_t mus_asymmetric_fm_unmodulated(mus_any *ptr, mus_float_t index)
  1825. {
  1826. asyfm *gen = (asyfm *)ptr;
  1827. mus_float_t result, mth;
  1828. mth = gen->ratio * gen->phase;
  1829. result = exp(index * gen->cosr * (gen->one + cos(mth))) * cos(gen->phase + index * gen->sinr * sin(mth));
  1830. /* second index factor added 4-Mar-02 */
  1831. gen->phase += gen->freq;
  1832. return(result);
  1833. }
  1834. static mus_any_class ASYMMETRIC_FM_CLASS = {
  1835. MUS_ASYMMETRIC_FM,
  1836. (char *)S_asymmetric_fm,
  1837. &free_asymmetric_fm,
  1838. &describe_asyfm,
  1839. &asyfm_equalp,
  1840. 0, 0, 0, 0,
  1841. &asyfm_freq,
  1842. &asyfm_set_freq,
  1843. &asyfm_phase,
  1844. &asyfm_set_phase,
  1845. &asyfm_r,
  1846. &asyfm_set_r,
  1847. &asyfm_increment,
  1848. &asyfm_set_increment,
  1849. &mus_asymmetric_fm,
  1850. MUS_NOT_SPECIAL,
  1851. NULL, 0,
  1852. &asyfm_ratio,
  1853. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1854. 0, 0, 0, 0, 0, 0, 0,
  1855. 0, 0, 0, 0,
  1856. &asyfm_reset,
  1857. 0,
  1858. &asyfm_copy
  1859. };
  1860. mus_any *mus_make_asymmetric_fm(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 1.0, ratio 1.0 */
  1861. {
  1862. asyfm *gen = NULL;
  1863. if (r == 0.0)
  1864. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_asymmetric_fm ": r can't be 0.0");
  1865. else
  1866. {
  1867. gen = (asyfm *)malloc(sizeof(asyfm));
  1868. gen->core = &ASYMMETRIC_FM_CLASS;
  1869. gen->freq = mus_hz_to_radians(freq);
  1870. gen->phase = phase;
  1871. gen->r = r;
  1872. gen->ratio = ratio;
  1873. gen->cosr = 0.5 * (r - (1.0 / r)); /* 0.5 factor for I/2 */
  1874. gen->sinr = 0.5 * (r + (1.0 / r));
  1875. if ((r > 1.0) ||
  1876. ((r < 0.0) && (r > -1.0)))
  1877. gen->one = -1.0;
  1878. else gen->one = 1.0;
  1879. }
  1880. return((mus_any *)gen);
  1881. }
  1882. /*---------------- nrxysin (sine-summation) and nrxycos ---------------- */
  1883. /* the generator uses x and y (frequencies), but it's very common to start up with 0 freqs
  1884. * and let the fm arg set the frequency, so it seems like we want to give the ratio between
  1885. * the frequencies at make time, rather than two (possibly dummy) frequencies).
  1886. * xy-ratio negative to build (via r) backwards.
  1887. */
  1888. #define MAX_R 0.999999
  1889. #define MIN_R -0.999999
  1890. typedef struct {
  1891. mus_any_class *core;
  1892. mus_float_t freq, phase;
  1893. int n;
  1894. mus_float_t norm, r, r_to_n_plus_1, r_squared_plus_1, y_over_x;
  1895. } nrxy;
  1896. static void free_nrxy(mus_any *ptr) {free(ptr);}
  1897. static void nrxy_reset(mus_any *ptr) {((nrxy *)ptr)->phase = 0.0;}
  1898. static mus_any *nrxy_copy(mus_any *ptr)
  1899. {
  1900. nrxy *g;
  1901. g = (nrxy *)malloc(sizeof(nrxy));
  1902. memcpy((void *)g, (void *)ptr, sizeof(nrxy));
  1903. return((mus_any *)g);
  1904. }
  1905. static mus_float_t nrxy_freq(mus_any *ptr) {return(mus_radians_to_hz(((nrxy *)ptr)->freq));}
  1906. static mus_float_t nrxy_set_freq(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  1907. static mus_float_t nrxy_increment(mus_any *ptr) {return(((nrxy *)ptr)->freq);}
  1908. static mus_float_t nrxy_set_increment(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->freq = val; return(val);}
  1909. static mus_float_t nrxy_phase(mus_any *ptr) {return(fmod(((nrxy *)ptr)->phase, TWO_PI));}
  1910. static mus_float_t nrxy_set_phase(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->phase = val; return(val);}
  1911. static mus_long_t nrxy_n(mus_any *ptr) {return((mus_long_t)(((nrxy *)ptr)->n));}
  1912. static mus_float_t nrxy_y_over_x(mus_any *ptr) {return(((nrxy *)ptr)->y_over_x);}
  1913. static mus_float_t nrxy_set_y_over_x(mus_any *ptr, mus_float_t val) {((nrxy *)ptr)->y_over_x = val; return(val);}
  1914. static mus_float_t nrxy_r(mus_any *ptr) {return(((nrxy *)ptr)->r);}
  1915. static mus_float_t nrxy_set_r(mus_any *ptr, mus_float_t r)
  1916. {
  1917. nrxy *gen = (nrxy *)ptr;
  1918. int n;
  1919. n = gen->n;
  1920. if (r > MAX_R) r = MAX_R;
  1921. if (r < MIN_R) r = MIN_R;
  1922. gen->r = r;
  1923. gen->r_to_n_plus_1 = pow(r, n + 1);
  1924. gen->r_squared_plus_1 = 1.0 + r * r;
  1925. if (n == 0)
  1926. gen->norm = 1.0;
  1927. else gen->norm = (pow(fabs(r), n + 1) - 1.0) / (fabs(r) - 1.0);
  1928. /* fabs here because if r<0.0, we line up at (2k-1)*pi rather than 2k*pi, but
  1929. * otherwise the waveform is identical
  1930. */
  1931. return(r);
  1932. }
  1933. static bool nrxy_equalp(mus_any *p1, mus_any *p2)
  1934. {
  1935. nrxy *g1 = (nrxy *)p1;
  1936. nrxy *g2 = (nrxy *)p2;
  1937. return((p1 == p2) ||
  1938. (((g1->core)->type == (g2->core)->type) &&
  1939. (g1->freq == g2->freq) &&
  1940. (g1->phase == g2->phase) &&
  1941. (g1->n == g2->n) &&
  1942. (g1->r == g2->r) &&
  1943. (g1->y_over_x == g2->y_over_x)));
  1944. }
  1945. bool mus_is_nrxysin(mus_any *ptr)
  1946. {
  1947. return((ptr) &&
  1948. (ptr->core->type == MUS_NRXYSIN));
  1949. }
  1950. static char *describe_nrxysin(mus_any *ptr)
  1951. {
  1952. nrxy *gen = (nrxy *)ptr;
  1953. char *describe_buffer;
  1954. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  1955. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, ratio: %.3f, phase: %.3f, n: %d, r: %.3f",
  1956. mus_name(ptr),
  1957. mus_frequency(ptr),
  1958. gen->y_over_x,
  1959. mus_phase(ptr),
  1960. gen->n,
  1961. nrxy_r(ptr));
  1962. return(describe_buffer);
  1963. }
  1964. mus_float_t mus_nrxysin(mus_any *ptr, mus_float_t fm)
  1965. {
  1966. /* Jolley 475 but 0..n rather than 0..n-1 */
  1967. /* see also Durell and Robson "Advanced Trigonometry" p 175 */
  1968. nrxy *gen = (nrxy *)ptr;
  1969. mus_float_t x, y, r, divisor;
  1970. int n;
  1971. x = gen->phase;
  1972. n = gen->n;
  1973. r = gen->r;
  1974. gen->phase += (gen->freq + fm);
  1975. if (gen->y_over_x == 1.0)
  1976. {
  1977. #if (!HAVE_SINCOS)
  1978. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(x)));
  1979. if (DIVISOR_NEAR_ZERO(divisor))
  1980. return(0.0);
  1981. return((sin(x) - gen->r_to_n_plus_1 * (sin(x * (n + 2)) - r * sin(x * (n + 1)))) / divisor);
  1982. #else
  1983. double sx, cx, snx, cnx;
  1984. sincos(x, &sx, &cx);
  1985. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cx));
  1986. if (DIVISOR_NEAR_ZERO(divisor))
  1987. return(0.0);
  1988. sincos((n + 1) * x, &snx, &cnx);
  1989. return((sx - gen->r_to_n_plus_1 * (sx * cnx + (cx - r) * snx)) / divisor);
  1990. #endif
  1991. }
  1992. #if HAVE_SINCOS
  1993. {
  1994. double xs, xc, ys, yc, nys, nyc, sin_x_y, sin_x_ny, sin_x_n1y, cos_x_ny;
  1995. y = x * gen->y_over_x;
  1996. sincos(y, &ys, &yc);
  1997. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * yc));
  1998. if (DIVISOR_NEAR_ZERO(divisor))
  1999. return(0.0);
  2000. sincos(x, &xs, &xc);
  2001. sincos(n * y, &nys, &nyc);
  2002. sin_x_y = (xs * yc - ys * xc);
  2003. sin_x_ny = (xs * nyc + nys * xc);
  2004. cos_x_ny = (xc * nyc - xs * nys);
  2005. sin_x_n1y = (sin_x_ny * yc + cos_x_ny * ys);
  2006. return((xs -
  2007. r * sin_x_y -
  2008. gen->r_to_n_plus_1 * (sin_x_n1y - r * sin_x_ny)) / divisor);
  2009. }
  2010. #else
  2011. y = x * gen->y_over_x;
  2012. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(y)));
  2013. if (DIVISOR_NEAR_ZERO(divisor))
  2014. return(0.0);
  2015. return((sin(x) -
  2016. r * sin(x - y) -
  2017. gen->r_to_n_plus_1 * (sin(x + (n + 1) * y) -
  2018. r * sin(x + n * y))) /
  2019. divisor);
  2020. #endif
  2021. }
  2022. static mus_float_t run_nrxysin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nrxysin(ptr, fm));}
  2023. static mus_any_class NRXYSIN_CLASS = {
  2024. MUS_NRXYSIN,
  2025. (char *)S_nrxysin,
  2026. &free_nrxy,
  2027. &describe_nrxysin,
  2028. &nrxy_equalp,
  2029. 0, 0,
  2030. &nrxy_n, 0,
  2031. &nrxy_freq,
  2032. &nrxy_set_freq,
  2033. &nrxy_phase,
  2034. &nrxy_set_phase,
  2035. &nrxy_r,
  2036. &nrxy_set_r,
  2037. &nrxy_increment,
  2038. &nrxy_set_increment,
  2039. &run_nrxysin,
  2040. MUS_NOT_SPECIAL,
  2041. NULL, 0,
  2042. &nrxy_y_over_x,
  2043. &nrxy_set_y_over_x,
  2044. 0, 0, 0, 0,
  2045. 0, 0, 0, 0,
  2046. 0, 0, 0, 0, 0, 0, 0,
  2047. 0, 0, 0, 0,
  2048. &nrxy_reset,
  2049. 0,
  2050. &nrxy_copy
  2051. };
  2052. mus_any *mus_make_nrxysin(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r)
  2053. {
  2054. nrxy *gen;
  2055. gen = (nrxy *)malloc(sizeof(nrxy));
  2056. gen->core = &NRXYSIN_CLASS;
  2057. gen->freq = mus_hz_to_radians(frequency);
  2058. gen->y_over_x = y_over_x;
  2059. gen->phase = 0.0;
  2060. gen->n = n;
  2061. nrxy_set_r((mus_any *)gen, r);
  2062. return((mus_any *)gen);
  2063. }
  2064. bool mus_is_nrxycos(mus_any *ptr)
  2065. {
  2066. return((ptr) &&
  2067. (ptr->core->type == MUS_NRXYCOS));
  2068. }
  2069. static char *describe_nrxycos(mus_any *ptr)
  2070. {
  2071. nrxy *gen = (nrxy *)ptr;
  2072. char *describe_buffer;
  2073. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  2074. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, ratio: %.3f, phase: %.3f, n: %d, r: %.3f",
  2075. mus_name(ptr),
  2076. mus_frequency(ptr),
  2077. gen->y_over_x,
  2078. mus_phase(ptr),
  2079. gen->n,
  2080. nrxy_r(ptr));
  2081. return(describe_buffer);
  2082. }
  2083. mus_float_t mus_nrxycos(mus_any *ptr, mus_float_t fm)
  2084. {
  2085. nrxy *gen = (nrxy *)ptr;
  2086. mus_float_t x, y, r, divisor;
  2087. int n;
  2088. x = gen->phase;
  2089. y = x * gen->y_over_x;
  2090. n = gen->n;
  2091. r = gen->r;
  2092. gen->phase += (gen->freq + fm);
  2093. #if HAVE_SINCOS
  2094. {
  2095. double xs, xc, ys, yc, nys, nyc, cos_x_y, cos_x_ny, cos_x_n1y, sin_x_ny;
  2096. sincos(y, &ys, &yc);
  2097. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * yc));
  2098. if (DIVISOR_NEAR_ZERO(divisor))
  2099. return(1.0);
  2100. sincos(x, &xs, &xc);
  2101. sincos(n * y, &nys, &nyc);
  2102. cos_x_y = (xc * yc + ys * xs);
  2103. sin_x_ny = (xs * nyc + nys * xc);
  2104. cos_x_ny = (xc * nyc - xs * nys);
  2105. cos_x_n1y = (cos_x_ny * yc - sin_x_ny * ys);
  2106. return((xc -
  2107. r * cos_x_y -
  2108. gen->r_to_n_plus_1 * (cos_x_n1y - r * cos_x_ny)) / divisor);
  2109. }
  2110. #else
  2111. divisor = gen->norm * (gen->r_squared_plus_1 - (2 * r * cos(y)));
  2112. if (DIVISOR_NEAR_ZERO(divisor))
  2113. return(1.0);
  2114. /* this can happen if r>0.9999999 or thereabouts;
  2115. */
  2116. return((cos(x) -
  2117. r * cos(x - y) -
  2118. gen->r_to_n_plus_1 * (cos(x + (n + 1) * y) -
  2119. r * cos(x + n * y))) /
  2120. divisor);
  2121. #endif
  2122. }
  2123. static mus_float_t run_nrxycos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_nrxycos(ptr, fm));}
  2124. static mus_any_class NRXYCOS_CLASS = {
  2125. MUS_NRXYCOS,
  2126. (char *)S_nrxycos,
  2127. &free_nrxy,
  2128. &describe_nrxycos,
  2129. &nrxy_equalp,
  2130. 0, 0,
  2131. &nrxy_n, 0,
  2132. &nrxy_freq,
  2133. &nrxy_set_freq,
  2134. &nrxy_phase,
  2135. &nrxy_set_phase,
  2136. &nrxy_r,
  2137. &nrxy_set_r,
  2138. &nrxy_increment,
  2139. &nrxy_set_increment,
  2140. &run_nrxycos,
  2141. MUS_NOT_SPECIAL,
  2142. NULL, 0,
  2143. &nrxy_y_over_x,
  2144. &nrxy_set_y_over_x,
  2145. 0, 0, 0, 0,
  2146. 0, 0, 0, 0,
  2147. 0, 0, 0, 0, 0, 0, 0,
  2148. 0, 0, 0, 0,
  2149. &nrxy_reset,
  2150. 0,
  2151. &nrxy_copy
  2152. };
  2153. mus_any *mus_make_nrxycos(mus_float_t frequency, mus_float_t y_over_x, int n, mus_float_t r)
  2154. {
  2155. nrxy *gen;
  2156. gen = (nrxy *)mus_make_nrxysin(frequency, y_over_x, n, r);
  2157. gen->core = &NRXYCOS_CLASS;
  2158. return((mus_any *)gen);
  2159. }
  2160. /* ---------------- rxykcos/sin ---------------- */
  2161. typedef struct {
  2162. mus_any_class *core;
  2163. mus_float_t r, ar;
  2164. mus_float_t freq, phase;
  2165. mus_float_t ratio;
  2166. } rxyk;
  2167. static void free_rxykcos(mus_any *ptr) {free(ptr);}
  2168. static void rxyk_reset(mus_any *ptr) {((rxyk *)ptr)->phase = 0.0;}
  2169. static mus_any *rxyk_copy(mus_any *ptr)
  2170. {
  2171. rxyk *g;
  2172. g = (rxyk *)malloc(sizeof(rxyk));
  2173. memcpy((void *)g, (void *)ptr, sizeof(rxyk));
  2174. return((mus_any *)g);
  2175. }
  2176. static mus_float_t rxyk_freq(mus_any *ptr) {return(mus_radians_to_hz(((rxyk *)ptr)->freq));}
  2177. static mus_float_t rxyk_set_freq(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  2178. static mus_float_t rxyk_increment(mus_any *ptr) {return(((rxyk *)ptr)->freq);}
  2179. static mus_float_t rxyk_set_increment(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->freq = val; return(val);}
  2180. static mus_float_t rxyk_phase(mus_any *ptr) {return(fmod(((rxyk *)ptr)->phase, TWO_PI));}
  2181. static mus_float_t rxyk_set_phase(mus_any *ptr, mus_float_t val) {((rxyk *)ptr)->phase = val; return(val);}
  2182. static mus_float_t rxyk_ratio(mus_any *ptr) {return(((rxyk *)ptr)->ratio);}
  2183. static mus_float_t rxyk_r(mus_any *ptr) {return(((rxyk *)ptr)->r);}
  2184. static mus_float_t rxyk_set_r(mus_any *ptr, mus_float_t val)
  2185. {
  2186. rxyk *gen = (rxyk *)ptr;
  2187. gen->r = val;
  2188. gen->ar = 1.0 / exp(fabs(val));
  2189. return(val);
  2190. }
  2191. static mus_float_t run_rxykcos(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rxykcos(ptr, fm));}
  2192. static mus_float_t run_rxyksin(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rxyksin(ptr, fm));}
  2193. static bool rxyk_equalp(mus_any *p1, mus_any *p2)
  2194. {
  2195. return((p1 == p2) ||
  2196. (((p1->core)->type == (p2->core)->type) &&
  2197. ((((rxyk *)p1)->freq) == (((rxyk *)p2)->freq)) &&
  2198. ((((rxyk *)p1)->phase) == (((rxyk *)p2)->phase)) &&
  2199. ((((rxyk *)p1)->ratio) == (((rxyk *)p2)->ratio)) &&
  2200. ((((rxyk *)p1)->r) == (((rxyk *)p2)->r))));
  2201. }
  2202. static char *describe_rxyk(mus_any *ptr)
  2203. {
  2204. char *describe_buffer;
  2205. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  2206. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, ratio: %.3f, r: %.3f",
  2207. mus_name(ptr),
  2208. mus_frequency(ptr),
  2209. mus_phase(ptr),
  2210. ((rxyk *)ptr)->ratio,
  2211. rxyk_r(ptr));
  2212. return(describe_buffer);
  2213. }
  2214. bool mus_is_rxykcos(mus_any *ptr)
  2215. {
  2216. return((ptr) &&
  2217. (ptr->core->type == MUS_RXYKCOS));
  2218. }
  2219. mus_float_t mus_rxykcos(mus_any *ptr, mus_float_t fm)
  2220. {
  2221. rxyk *gen = (rxyk *)ptr;
  2222. mus_float_t result, rx;
  2223. rx = gen->ratio * gen->phase;
  2224. result = gen->ar * exp(gen->r * cos(rx)) * cos(gen->phase + (gen->r * sin(rx)));
  2225. gen->phase += (fm + gen->freq);
  2226. return(result);
  2227. }
  2228. static mus_any_class RXYKCOS_CLASS = {
  2229. MUS_RXYKCOS,
  2230. (char *)S_rxykcos,
  2231. &free_rxykcos,
  2232. &describe_rxyk,
  2233. &rxyk_equalp,
  2234. 0, 0, 0, 0,
  2235. &rxyk_freq,
  2236. &rxyk_set_freq,
  2237. &rxyk_phase,
  2238. &rxyk_set_phase,
  2239. &rxyk_r,
  2240. &rxyk_set_r,
  2241. &rxyk_increment,
  2242. &rxyk_set_increment,
  2243. &run_rxykcos,
  2244. MUS_NOT_SPECIAL,
  2245. NULL, 0,
  2246. &rxyk_ratio,
  2247. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2248. 0, 0, 0, 0, 0, 0, 0,
  2249. 0, 0, 0, 0,
  2250. &rxyk_reset,
  2251. 0,
  2252. &rxyk_copy
  2253. };
  2254. mus_any *mus_make_rxykcos(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 0.5, ratio 1.0 */
  2255. {
  2256. rxyk *gen = NULL;
  2257. gen = (rxyk *)malloc(sizeof(rxyk));
  2258. gen->core = &RXYKCOS_CLASS;
  2259. gen->freq = mus_hz_to_radians(freq);
  2260. gen->phase = phase;
  2261. gen->r = r;
  2262. gen->ar = 1.0 / exp(fabs(r));
  2263. gen->ratio = ratio;
  2264. return((mus_any *)gen);
  2265. }
  2266. bool mus_is_rxyksin(mus_any *ptr)
  2267. {
  2268. return((ptr) &&
  2269. (ptr->core->type == MUS_RXYKSIN));
  2270. }
  2271. mus_float_t mus_rxyksin(mus_any *ptr, mus_float_t fm)
  2272. {
  2273. rxyk *gen = (rxyk *)ptr;
  2274. mus_float_t result, rx;
  2275. rx = gen->ratio * gen->phase;
  2276. result = gen->ar * exp(gen->r * cos(rx)) * sin(gen->phase + (gen->r * sin(rx)));
  2277. gen->phase += (fm + gen->freq);
  2278. return(result);
  2279. }
  2280. static mus_any_class RXYKSIN_CLASS = {
  2281. MUS_RXYKSIN,
  2282. (char *)S_rxyksin,
  2283. &free_rxykcos,
  2284. &describe_rxyk,
  2285. &rxyk_equalp,
  2286. 0, 0, 0, 0,
  2287. &rxyk_freq,
  2288. &rxyk_set_freq,
  2289. &rxyk_phase,
  2290. &rxyk_set_phase,
  2291. &rxyk_r,
  2292. &rxyk_set_r,
  2293. &rxyk_increment,
  2294. &rxyk_set_increment,
  2295. &run_rxyksin,
  2296. MUS_NOT_SPECIAL,
  2297. NULL, 0,
  2298. &rxyk_ratio,
  2299. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2300. 0, 0, 0, 0, 0, 0, 0,
  2301. 0, 0, 0, 0,
  2302. &rxyk_reset,
  2303. 0,
  2304. &rxyk_copy
  2305. };
  2306. mus_any *mus_make_rxyksin(mus_float_t freq, mus_float_t phase, mus_float_t r, mus_float_t ratio) /* r default 0.5, ratio 1.0 */
  2307. {
  2308. rxyk *gen = NULL;
  2309. gen = (rxyk *)malloc(sizeof(rxyk));
  2310. gen->core = &RXYKSIN_CLASS;
  2311. gen->freq = mus_hz_to_radians(freq);
  2312. gen->phase = phase;
  2313. gen->r = r;
  2314. gen->ar = 1.0 / exp(fabs(r));
  2315. gen->ratio = ratio;
  2316. return((mus_any *)gen);
  2317. }
  2318. /* ---------------- table lookup ---------------- */
  2319. typedef struct {
  2320. mus_any_class *core;
  2321. mus_float_t freq, internal_mag, phase;
  2322. mus_float_t *table;
  2323. mus_long_t table_size;
  2324. mus_interp_t type;
  2325. bool table_allocated;
  2326. mus_float_t yn1;
  2327. mus_float_t (*tbl_look)(mus_any *ptr, mus_float_t fm);
  2328. mus_float_t (*tbl_look_unmod)(mus_any *ptr);
  2329. } tbl;
  2330. mus_float_t *mus_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize)
  2331. {
  2332. int partial, k;
  2333. if (!table) return(NULL);
  2334. memset((void *)table, 0, table_size * sizeof(mus_float_t));
  2335. for (partial = 0, k = 1; partial < partials; partial++, k += 2)
  2336. {
  2337. mus_float_t amp;
  2338. amp = partial_data[k];
  2339. if (amp != 0.0)
  2340. {
  2341. mus_long_t i;
  2342. mus_float_t freq, angle;
  2343. freq = (partial_data[partial * 2] * TWO_PI) / (mus_float_t)table_size;
  2344. for (i = 0, angle = 0.0; i < table_size; i++, angle += freq)
  2345. table[i] += amp * sin(angle);
  2346. }
  2347. }
  2348. if (normalize)
  2349. return(array_normalize(table, table_size));
  2350. return(table);
  2351. }
  2352. mus_float_t *mus_phase_partials_to_wave(mus_float_t *partial_data, int partials, mus_float_t *table, mus_long_t table_size, bool normalize)
  2353. {
  2354. int partial, k, n;
  2355. if (!table) return(NULL);
  2356. memset((void *)table, 0, table_size * sizeof(mus_float_t));
  2357. for (partial = 0, k = 1, n = 2; partial < partials; partial++, k += 3, n += 3)
  2358. {
  2359. mus_float_t amp;
  2360. amp = partial_data[k];
  2361. if (amp != 0.0)
  2362. {
  2363. mus_long_t i;
  2364. mus_float_t freq, angle;
  2365. freq = (partial_data[partial * 3] * TWO_PI) / (mus_float_t)table_size;
  2366. for (i = 0, angle = partial_data[n]; i < table_size; i++, angle += freq)
  2367. table[i] += amp * sin(angle);
  2368. }
  2369. }
  2370. if (normalize)
  2371. return(array_normalize(table, table_size));
  2372. return(table);
  2373. }
  2374. mus_float_t mus_table_lookup(mus_any *ptr, mus_float_t fm)
  2375. {
  2376. return(((tbl *)ptr)->tbl_look(ptr, fm));
  2377. }
  2378. static mus_float_t table_look_linear(mus_any *ptr, mus_float_t fm)
  2379. {
  2380. tbl *gen = (tbl *)ptr;
  2381. /* we're checking already for out-of-range indices, so mus_array_interp is more than we need */
  2382. mus_long_t int_part;
  2383. mus_float_t frac_part, f1;
  2384. int_part = (mus_long_t)(gen->phase); /* floor(gen->phase) -- slow! modf is even worse */
  2385. frac_part = gen->phase - int_part;
  2386. f1 = gen->table[int_part];
  2387. int_part++;
  2388. if (int_part == gen->table_size)
  2389. gen->yn1 = f1 + frac_part * (gen->table[0] - f1);
  2390. else gen->yn1 = f1 + frac_part * (gen->table[int_part] - f1);
  2391. gen->phase += (gen->freq + (fm * gen->internal_mag));
  2392. if ((gen->phase >= gen->table_size) ||
  2393. (gen->phase < 0.0))
  2394. {
  2395. gen->phase = fmod(gen->phase, gen->table_size);
  2396. if (gen->phase < 0.0)
  2397. gen->phase += gen->table_size;
  2398. }
  2399. return(gen->yn1);
  2400. }
  2401. static mus_float_t table_look_any(mus_any *ptr, mus_float_t fm)
  2402. {
  2403. tbl *gen = (tbl *)ptr;
  2404. gen->yn1 = mus_interpolate(gen->type, gen->phase, gen->table, gen->table_size, gen->yn1);
  2405. gen->phase += (gen->freq + (fm * gen->internal_mag));
  2406. if ((gen->phase >= gen->table_size) ||
  2407. (gen->phase < 0.0))
  2408. {
  2409. gen->phase = fmod(gen->phase, gen->table_size);
  2410. if (gen->phase < 0.0)
  2411. gen->phase += gen->table_size;
  2412. }
  2413. return(gen->yn1);
  2414. }
  2415. mus_float_t mus_table_lookup_unmodulated(mus_any *ptr)
  2416. {
  2417. return(((tbl *)ptr)->tbl_look_unmod(ptr));
  2418. }
  2419. static mus_float_t table_look_unmodulated_linear(mus_any *ptr)
  2420. {
  2421. tbl *gen = (tbl *)ptr;
  2422. mus_long_t int_part;
  2423. mus_float_t frac_part, f1;
  2424. int_part = (mus_long_t)(gen->phase);
  2425. frac_part = gen->phase - int_part;
  2426. f1 = gen->table[int_part];
  2427. int_part++;
  2428. if (int_part == gen->table_size)
  2429. f1 += frac_part * (gen->table[0] - f1);
  2430. else f1 += frac_part * (gen->table[int_part] - f1);
  2431. gen->phase += gen->freq;
  2432. if ((gen->phase >= gen->table_size) ||
  2433. (gen->phase < 0.0))
  2434. {
  2435. gen->phase = fmod(gen->phase, gen->table_size);
  2436. if (gen->phase < 0.0)
  2437. gen->phase += gen->table_size;
  2438. }
  2439. return(f1);
  2440. }
  2441. static mus_float_t table_look_unmodulated_any(mus_any *ptr)
  2442. {
  2443. tbl *gen = (tbl *)ptr;
  2444. gen->yn1 = mus_interpolate(gen->type, gen->phase, gen->table, gen->table_size, gen->yn1);
  2445. gen->phase += gen->freq;
  2446. if ((gen->phase >= gen->table_size) ||
  2447. (gen->phase < 0.0))
  2448. {
  2449. gen->phase = fmod(gen->phase, gen->table_size);
  2450. if (gen->phase < 0.0)
  2451. gen->phase += gen->table_size;
  2452. }
  2453. return(gen->yn1);
  2454. }
  2455. static mus_float_t run_table_lookup(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(((tbl *)ptr)->tbl_look(ptr, fm)); }
  2456. bool mus_is_table_lookup(mus_any *ptr)
  2457. {
  2458. return((ptr) &&
  2459. (ptr->core->type == MUS_TABLE_LOOKUP));
  2460. }
  2461. static mus_long_t table_lookup_length(mus_any *ptr) {return(((tbl *)ptr)->table_size);}
  2462. static mus_float_t *table_lookup_data(mus_any *ptr) {return(((tbl *)ptr)->table);}
  2463. static mus_float_t table_lookup_freq(mus_any *ptr) {return((((tbl *)ptr)->freq * sampling_rate) / (((tbl *)ptr)->table_size));}
  2464. static mus_float_t table_lookup_set_freq(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->freq = (val * ((tbl *)ptr)->table_size) / sampling_rate; return(val);}
  2465. static mus_float_t table_lookup_increment(mus_any *ptr) {return(((tbl *)ptr)->freq);}
  2466. static mus_float_t table_lookup_set_increment(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->freq = val; return(val);}
  2467. static mus_float_t table_lookup_phase(mus_any *ptr) {return(fmod(((TWO_PI * ((tbl *)ptr)->phase) / ((tbl *)ptr)->table_size), TWO_PI));}
  2468. static mus_float_t table_lookup_set_phase(mus_any *ptr, mus_float_t val) {((tbl *)ptr)->phase = (val * ((tbl *)ptr)->table_size) / TWO_PI; return(val);}
  2469. static int table_lookup_interp_type(mus_any *ptr) {return((int)(((tbl *)ptr)->type));} /* ints here and elsewhere to fit mus_channels method = interp-type */
  2470. static void table_lookup_reset(mus_any *ptr) {((tbl *)ptr)->phase = 0.0;}
  2471. static char *describe_table_lookup(mus_any *ptr)
  2472. {
  2473. char *describe_buffer;
  2474. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  2475. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, length: %d, interp: %s",
  2476. mus_name(ptr),
  2477. mus_frequency(ptr),
  2478. mus_phase(ptr),
  2479. (int)mus_length(ptr),
  2480. interp_type_to_string(table_lookup_interp_type(ptr)));
  2481. return(describe_buffer);
  2482. }
  2483. static bool table_lookup_equalp(mus_any *p1, mus_any *p2)
  2484. {
  2485. tbl *t1 = (tbl *)p1;
  2486. tbl *t2 = (tbl *)p2;
  2487. if (p1 == p2) return(true);
  2488. return((t1) && (t2) &&
  2489. (t1->core->type == t2->core->type) &&
  2490. (t1->table_size == t2->table_size) &&
  2491. (t1->freq == t2->freq) &&
  2492. (t1->phase == t2->phase) &&
  2493. (t1->type == t2->type) &&
  2494. (t1->internal_mag == t2->internal_mag) &&
  2495. (clm_arrays_are_equal(t1->table, t2->table, t1->table_size)));
  2496. }
  2497. static void free_table_lookup(mus_any *ptr)
  2498. {
  2499. tbl *gen = (tbl *)ptr;
  2500. if ((gen->table) && (gen->table_allocated)) free(gen->table);
  2501. free(gen);
  2502. }
  2503. static mus_any *tbl_copy(mus_any *ptr)
  2504. {
  2505. mus_long_t bytes;
  2506. tbl *g, *p;
  2507. p = (tbl *)ptr;
  2508. g = (tbl *)malloc(sizeof(tbl));
  2509. memcpy((void *)g, (void *)ptr, sizeof(tbl));
  2510. bytes = g->table_size * sizeof(mus_float_t);
  2511. g->table = (mus_float_t *)malloc(bytes);
  2512. memcpy((void *)(g->table), (void *)(p->table), bytes);
  2513. g->table_allocated = true;
  2514. return((mus_any *)g);
  2515. }
  2516. static mus_float_t *table_set_data(mus_any *ptr, mus_float_t *val)
  2517. {
  2518. tbl *gen = (tbl *)ptr;
  2519. if (gen->table_allocated) {free(gen->table); gen->table_allocated = false;}
  2520. gen->table = val;
  2521. return(val);
  2522. }
  2523. static mus_any_class TABLE_LOOKUP_CLASS = {
  2524. MUS_TABLE_LOOKUP,
  2525. (char *)S_table_lookup,
  2526. &free_table_lookup,
  2527. &describe_table_lookup,
  2528. &table_lookup_equalp,
  2529. &table_lookup_data,
  2530. &table_set_data,
  2531. &table_lookup_length,
  2532. 0,
  2533. &table_lookup_freq,
  2534. &table_lookup_set_freq,
  2535. &table_lookup_phase,
  2536. &table_lookup_set_phase,
  2537. &fallback_scaler, 0,
  2538. &table_lookup_increment,
  2539. &table_lookup_set_increment,
  2540. &run_table_lookup,
  2541. MUS_NOT_SPECIAL,
  2542. NULL,
  2543. &table_lookup_interp_type,
  2544. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2545. 0, 0, 0, 0, 0, 0, 0,
  2546. 0, 0, 0, 0,
  2547. &table_lookup_reset,
  2548. 0, &tbl_copy
  2549. };
  2550. mus_any *mus_make_table_lookup(mus_float_t freq, mus_float_t phase, mus_float_t *table, mus_long_t table_size, mus_interp_t type)
  2551. {
  2552. tbl *gen;
  2553. gen = (tbl *)malloc(sizeof(tbl));
  2554. gen->core = &TABLE_LOOKUP_CLASS;
  2555. gen->table_size = table_size;
  2556. gen->internal_mag = table_size / TWO_PI;
  2557. gen->freq = (freq * table_size) / sampling_rate;
  2558. gen->phase = (fmod(phase, TWO_PI) * table_size) / TWO_PI;
  2559. gen->type = type;
  2560. if (type == MUS_INTERP_LINEAR)
  2561. {
  2562. gen->tbl_look = table_look_linear;
  2563. gen->tbl_look_unmod = table_look_unmodulated_linear;
  2564. }
  2565. else
  2566. {
  2567. gen->tbl_look = table_look_any;
  2568. gen->tbl_look_unmod = table_look_unmodulated_any;
  2569. }
  2570. gen->yn1 = 0.0;
  2571. if (table)
  2572. {
  2573. gen->table = table;
  2574. gen->table_allocated = false;
  2575. }
  2576. else
  2577. {
  2578. gen->table = (mus_float_t *)calloc(table_size, sizeof(mus_float_t));
  2579. gen->table_allocated = true;
  2580. }
  2581. return((mus_any *)gen);
  2582. }
  2583. /* ---------------- polywave ---------------- */
  2584. mus_float_t *mus_partials_to_polynomial(int npartials, mus_float_t *partials, mus_polynomial_t kind)
  2585. {
  2586. /* coeffs returned in partials */
  2587. int i;
  2588. mus_long_t *T0, *T1, *Tn;
  2589. mus_float_t *Cc1;
  2590. T0 = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t));
  2591. T1 = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t));
  2592. Tn = (mus_long_t *)calloc(npartials + 1, sizeof(mus_long_t));
  2593. Cc1 = (mus_float_t *)calloc(npartials + 1, sizeof(mus_float_t));
  2594. if (kind == MUS_CHEBYSHEV_FIRST_KIND)
  2595. T0[0] = 1;
  2596. else T0[0] = 0;
  2597. T1[1] = 1;
  2598. Cc1[0] = partials[0]; /* DC requested? */
  2599. for (i = 1; i < npartials; i++)
  2600. {
  2601. int k;
  2602. mus_float_t amp;
  2603. amp = partials[i];
  2604. if (amp != 0.0)
  2605. {
  2606. if (kind == MUS_CHEBYSHEV_FIRST_KIND)
  2607. for (k = 0; k <= i; k++)
  2608. Cc1[k] += (amp * T1[k]);
  2609. else
  2610. for (k = 1; k <= i; k++)
  2611. Cc1[k - 1] += (amp * T1[k]);
  2612. }
  2613. for (k = i + 1; k > 0; k--)
  2614. Tn[k] = (2 * T1[k - 1]) - T0[k];
  2615. Tn[0] = -T0[0];
  2616. for (k = i + 1; k >= 0; k--)
  2617. {
  2618. T0[k] = T1[k];
  2619. T1[k] = Tn[k];
  2620. }
  2621. }
  2622. for (i = 0; i < npartials; i++)
  2623. partials[i] = Cc1[i];
  2624. free(T0);
  2625. free(T1);
  2626. free(Tn);
  2627. free(Cc1);
  2628. return(partials);
  2629. }
  2630. mus_float_t *mus_normalize_partials(int num_partials, mus_float_t *partials)
  2631. {
  2632. int i;
  2633. mus_float_t sum = 0.0;
  2634. for (i = 0; i < num_partials; i++)
  2635. sum += fabs(partials[2 * i + 1]);
  2636. if ((sum != 0.0) &&
  2637. (sum != 1.0))
  2638. {
  2639. sum = 1.0 / sum;
  2640. for (i = 0; i < num_partials; i++)
  2641. partials[2 * i + 1] *= sum;
  2642. }
  2643. return(partials);
  2644. }
  2645. typedef struct {
  2646. mus_any_class *core;
  2647. mus_float_t phase, freq;
  2648. mus_float_t *coeffs, *ucoeffs;
  2649. int n, cheby_choice;
  2650. mus_float_t index;
  2651. mus_float_t (*polyw)(mus_any *ptr, mus_float_t fm);
  2652. } pw;
  2653. mus_float_t (*mus_polywave_function(mus_any *g))(mus_any *gen, mus_float_t fm)
  2654. {
  2655. if (mus_is_polywave(g))
  2656. return(((pw *)g)->polyw);
  2657. return(NULL);
  2658. }
  2659. static void free_pw(mus_any *pt) {free(pt);}
  2660. static mus_any *pw_copy(mus_any *ptr)
  2661. {
  2662. pw *g;
  2663. g = (pw *)malloc(sizeof(pw));
  2664. memcpy((void *)g, (void *)ptr, sizeof(pw));
  2665. return((mus_any *)g);
  2666. }
  2667. static void pw_reset(mus_any *ptr)
  2668. {
  2669. pw *gen = (pw *)ptr;
  2670. gen->phase = 0.0;
  2671. }
  2672. static bool pw_equalp(mus_any *p1, mus_any *p2)
  2673. {
  2674. pw *w1 = (pw *)p1;
  2675. pw *w2 = (pw *)p2;
  2676. if (p1 == p2) return(true);
  2677. return((w1) && (w2) &&
  2678. (w1->core->type == w2->core->type) &&
  2679. (w1->freq == w2->freq) &&
  2680. (w1->phase == w2->phase) &&
  2681. (w1->n == w2->n) &&
  2682. (w1->index == w2->index) &&
  2683. (w1->cheby_choice == w2->cheby_choice) &&
  2684. (clm_arrays_are_equal(w1->coeffs, w2->coeffs, w1->n)));
  2685. }
  2686. static mus_float_t pw_freq(mus_any *ptr) {return(mus_radians_to_hz(((pw *)ptr)->freq));}
  2687. static mus_float_t pw_set_freq(mus_any *ptr, mus_float_t val) {((pw *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  2688. static mus_float_t pw_increment(mus_any *ptr) {return(((pw *)ptr)->freq);}
  2689. static mus_float_t pw_set_increment(mus_any *ptr, mus_float_t val) {((pw *)ptr)->freq = val; return(val);}
  2690. static mus_float_t pw_phase(mus_any *ptr) {return(fmod(((pw *)ptr)->phase, TWO_PI));}
  2691. static mus_float_t pw_set_phase(mus_any *ptr, mus_float_t val) {((pw *)ptr)->phase = val; return(val);}
  2692. static mus_long_t pw_n(mus_any *ptr) {return(((pw *)ptr)->n);}
  2693. static mus_long_t pw_set_n(mus_any *ptr, mus_long_t val) {((pw *)ptr)->n = (int)val; return(val);}
  2694. static mus_float_t *pw_data(mus_any *ptr) {return(((pw *)ptr)->coeffs);}
  2695. static mus_float_t *pw_udata(mus_any *ptr) {return(((pw *)ptr)->ucoeffs);}
  2696. static mus_float_t *pw_set_data(mus_any *ptr, mus_float_t *val) {((pw *)ptr)->coeffs = val; return(val);}
  2697. static mus_float_t pw_xcoeff(mus_any *ptr, int index) {return(((pw *)ptr)->coeffs[index]);}
  2698. static mus_float_t pw_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {((pw *)ptr)->coeffs[index] = val; return(val);}
  2699. static mus_float_t pw_ycoeff(mus_any *ptr, int index) {if (((pw *)ptr)->ucoeffs) return(((pw *)ptr)->ucoeffs[index]); return(0.0);}
  2700. static mus_float_t pw_set_ycoeff(mus_any *ptr, int index, mus_float_t val) {if (((pw *)ptr)->ucoeffs) ((pw *)ptr)->ucoeffs[index] = val; return(val);}
  2701. static mus_float_t pw_index(mus_any *ptr) {return(((pw *)ptr)->index);}
  2702. static mus_float_t pw_set_index(mus_any *ptr, mus_float_t val) {((pw *)ptr)->index = val; return(val);}
  2703. static int pw_choice(mus_any *ptr) {return(((pw *)ptr)->cheby_choice);}
  2704. mus_float_t mus_chebyshev_tu_sum(mus_float_t x, int n, mus_float_t *tn, mus_float_t *un)
  2705. {
  2706. /* the Clenshaw algorithm -- beware of -cos(nx) where you'd expect cos(nx) */
  2707. mus_float_t x2, tb, tb1 = 0.0, tb2, cx, ub, ub1 = 0.0;
  2708. mus_float_t *tp, *up;
  2709. cx = cos(x);
  2710. x2 = 2.0 * cx;
  2711. tp = (mus_float_t *)(tn + n - 1);
  2712. up = (mus_float_t *)(un + n - 1);
  2713. tb = (*tp--);
  2714. ub = (*up--);
  2715. while (up != un)
  2716. {
  2717. mus_float_t ub2;
  2718. tb2 = tb1;
  2719. tb1 = tb;
  2720. tb = x2 * tb1 - tb2 + (*tp--);
  2721. ub2 = ub1;
  2722. ub1 = ub;
  2723. ub = x2 * ub1 - ub2 + (*up--);
  2724. }
  2725. tb2 = tb1;
  2726. tb1 = tb;
  2727. tb = x2 * tb1 - tb2 + tn[0];
  2728. return((mus_float_t)((tb - tb1 * cx) + (sin(x) * ub)));
  2729. }
  2730. mus_float_t mus_chebyshev_t_sum(mus_float_t x, int n, mus_float_t *tn)
  2731. {
  2732. int i;
  2733. mus_float_t x2, b, b1 = 0.0, cx;
  2734. cx = cos(x);
  2735. x2 = 2.0 * cx;
  2736. /* Tn calc */
  2737. b = tn[n - 1];
  2738. for (i = n - 2; i >= 0; i--)
  2739. {
  2740. mus_float_t b2;
  2741. b2 = b1;
  2742. b1 = b;
  2743. b = x2 * b1 - b2 + tn[i];
  2744. }
  2745. return((mus_float_t)(b - b1 * cx));
  2746. }
  2747. #if 0
  2748. /* here is the trick to do odd Tn without doing the intervening evens: */
  2749. (define (mus-chebyshev-odd-t-sum x n t2n)
  2750. (let* ((b1 0.0)
  2751. (b2 0.0)
  2752. (cx1 (cos x))
  2753. (cx (- (* 2 cx1 cx1) 1))
  2754. (x2 (* 2.0 cx))
  2755. (b (vct-ref t2n (- n 1))))
  2756. (do ((i (- n 2) (1- i)))
  2757. ((< i 0))
  2758. (set! b2 b1)
  2759. (set! b1 b)
  2760. (set! b (- (+ (* b1 x2) (vct-ref t2n i)) b2)))
  2761. (* cx1 (- b b1))))
  2762. (with-sound ()
  2763. (let ((t2n (vct 0.5 0.25 0.25))
  2764. (x 0.0)
  2765. (dx (hz->radians 10.0)))
  2766. (do ((i 0 (+ i 1)))
  2767. ((= i 22050))
  2768. (outa i (mus-chebyshev-odd-t-sum x 3 t2n))
  2769. (set! x (+ x dx)))))
  2770. #endif
  2771. mus_float_t mus_chebyshev_u_sum(mus_float_t x, int n, mus_float_t *un)
  2772. {
  2773. int i;
  2774. mus_float_t x2, b, b1 = 0.0, cx;
  2775. cx = cos(x);
  2776. x2 = 2.0 * cx;
  2777. /* Un calc */
  2778. b = un[n - 1];
  2779. for (i = n - 2; i > 0; i--)
  2780. {
  2781. mus_float_t b2;
  2782. b2 = b1;
  2783. b1 = b;
  2784. b = x2 * b1 - b2 + un[i];
  2785. }
  2786. return((mus_float_t)(sin(x) * b));
  2787. }
  2788. static mus_float_t mus_chebyshev_t_sum_with_index(mus_float_t x, mus_float_t index, int n, mus_float_t *tn)
  2789. {
  2790. int i;
  2791. mus_float_t x2, b, b1 = 0.0, b2, cx;
  2792. cx = index * cos(x);
  2793. x2 = 2.0 * cx;
  2794. /* Tn calc */
  2795. b = tn[n - 1];
  2796. i = n - 2;
  2797. while (i >= 4)
  2798. {
  2799. b2 = b1;
  2800. b1 = b;
  2801. b = x2 * b1 - b2 + tn[i--];
  2802. b2 = b1;
  2803. b1 = b;
  2804. b = x2 * b1 - b2 + tn[i--];
  2805. b2 = b1;
  2806. b1 = b;
  2807. b = x2 * b1 - b2 + tn[i--];
  2808. b2 = b1;
  2809. b1 = b;
  2810. b = x2 * b1 - b2 + tn[i--];
  2811. }
  2812. for (; i >= 0; i--)
  2813. {
  2814. b2 = b1;
  2815. b1 = b;
  2816. b = x2 * b1 - b2 + tn[i];
  2817. }
  2818. return((mus_float_t)(b - b1 * cx));
  2819. }
  2820. static mus_float_t mus_chebyshev_t_sum_with_index_2(mus_float_t x, mus_float_t index, int n, mus_float_t *tn)
  2821. {
  2822. int i;
  2823. mus_float_t x2, b, b1 = 0.0, cx;
  2824. cx = index * cos(x);
  2825. x2 = 2.0 * cx;
  2826. /* Tn calc */
  2827. b = tn[n - 1];
  2828. for (i = n - 2; i > 0;)
  2829. {
  2830. mus_float_t b2;
  2831. b2 = b1;
  2832. b1 = b;
  2833. b = x2 * b1 - b2 + tn[i--];
  2834. b2 = b1;
  2835. b1 = b;
  2836. b = x2 * b1 - b2 + tn[i--];
  2837. }
  2838. return((mus_float_t)(b - b1 * cx));
  2839. }
  2840. static mus_float_t mus_chebyshev_t_sum_with_index_3(mus_float_t x, mus_float_t index, int n, mus_float_t *tn)
  2841. {
  2842. int i;
  2843. mus_float_t x2, b, b1 = 0.0, cx;
  2844. cx = index * cos(x);
  2845. x2 = 2.0 * cx;
  2846. /* Tn calc */
  2847. b = tn[n - 1];
  2848. for (i = n - 2; i > 0;)
  2849. {
  2850. mus_float_t b2;
  2851. b2 = b1;
  2852. b1 = b;
  2853. b = x2 * b1 - b2 + tn[i--];
  2854. b2 = b1;
  2855. b1 = b;
  2856. b = x2 * b1 - b2 + tn[i--];
  2857. b2 = b1;
  2858. b1 = b;
  2859. b = x2 * b1 - b2 + tn[i--];
  2860. }
  2861. return((mus_float_t)(b - b1 * cx));
  2862. }
  2863. static mus_float_t mus_chebyshev_t_sum_with_index_5(mus_float_t x, mus_float_t index, int n, mus_float_t *tn)
  2864. {
  2865. int i;
  2866. mus_float_t x2, b, b1 = 0.0, cx;
  2867. cx = index * cos(x);
  2868. x2 = 2.0 * cx;
  2869. /* Tn calc */
  2870. b = tn[n - 1];
  2871. for (i = n - 2; i > 0;) /* this was >= ?? (also cases above) -- presumably a copy-and-paste typo? */
  2872. {
  2873. mus_float_t b2;
  2874. b2 = b1;
  2875. b1 = b;
  2876. b = x2 * b1 - b2 + tn[i--];
  2877. b2 = b1;
  2878. b1 = b;
  2879. b = x2 * b1 - b2 + tn[i--];
  2880. b2 = b1;
  2881. b1 = b;
  2882. b = x2 * b1 - b2 + tn[i--];
  2883. b2 = b1;
  2884. b1 = b;
  2885. b = x2 * b1 - b2 + tn[i--];
  2886. b2 = b1;
  2887. b1 = b;
  2888. b = x2 * b1 - b2 + tn[i--];
  2889. }
  2890. return((mus_float_t)(b - b1 * cx));
  2891. }
  2892. static mus_float_t mus_chebyshev_u_sum_with_index(mus_float_t x, mus_float_t index, int n, mus_float_t *un)
  2893. {
  2894. int i;
  2895. mus_float_t x2, b, b1 = 0.0, cx;
  2896. cx = index * cos(x);
  2897. x2 = 2.0 * cx;
  2898. /* Un calc */
  2899. b = un[n - 1];
  2900. for (i = n - 2; i > 0; i--)
  2901. {
  2902. mus_float_t b2;
  2903. b2 = b1;
  2904. b1 = b;
  2905. b = x2 * b1 - b2 + un[i];
  2906. }
  2907. return((mus_float_t)(sin(x) * b + un[0])); /* don't drop the constant, 16-Jan-14 */
  2908. }
  2909. /* (with-sound () (let ((p (make-polywave 100 (list 0 0.5 1 -.2) mus-chebyshev-second-kind))) (do ((i 0 (+ i 1))) ((= i 1000)) (outa i (polywave p)))))
  2910. */
  2911. static mus_float_t polyw_second_2(mus_any *ptr, mus_float_t fm)
  2912. {
  2913. pw *gen = (pw *)ptr;
  2914. mus_float_t x;
  2915. x = gen->phase; /* this order (as opposed to saving the full expr below) is much faster?! */
  2916. gen->phase += (gen->freq + fm);
  2917. return(gen->coeffs[1] * sin(x) + gen->coeffs[0]);
  2918. }
  2919. static mus_float_t polyw_first_1(mus_any *ptr, mus_float_t fm)
  2920. {
  2921. pw *gen = (pw *)ptr;
  2922. mus_float_t x;
  2923. x = gen->phase;
  2924. gen->phase += (gen->freq + fm);
  2925. return(gen->index * cos(x));
  2926. }
  2927. static mus_float_t polyw_first_3(mus_any *ptr, mus_float_t fm)
  2928. {
  2929. pw *gen = (pw *)ptr;
  2930. mus_float_t x, cx;
  2931. mus_float_t *tn;
  2932. x = gen->phase;
  2933. tn = gen->coeffs;
  2934. gen->phase += (gen->freq + fm);
  2935. cx = cos(x);
  2936. return((2.0 * cx * tn[2] + tn[1]) * cx - tn[2]);
  2937. /* b = x2 * b1 - b2;, then return(b - b1 * cx)
  2938. * but x2 = 2 * cx, so b1*(x2 - cx) -> b1 * cx
  2939. * and the final recursion unrolls. The old code
  2940. * (which thought tn[0] might not be 0.0) was:
  2941. * cx = cos(x);
  2942. * x2 = 2.0 * cx;
  2943. * b = tn[2];
  2944. * b2 = b1; -- but b1 is 0
  2945. * b1 = b; -- b not used so this is tn[2]
  2946. * b = x2 * b1 - b2 + tn[1]; -- b2 is 0.0
  2947. * b2 = b1;
  2948. * b1 = b;
  2949. * b = x2 * b1 - b2 + tn[0];
  2950. * return(b - b1 * cx);
  2951. */
  2952. }
  2953. /* (with-sound () (let ((p (make-polywave 100 (list 1 .5 2 .25)))) (do ((i 0 (+ i 1))) ((= i 30000)) (outa i (polywave p))))) */
  2954. static mus_float_t polyw_first_4(mus_any *ptr, mus_float_t fm)
  2955. {
  2956. pw *gen = (pw *)ptr;
  2957. mus_float_t x, x2, b, cx;
  2958. mus_float_t *tn;
  2959. x = gen->phase;
  2960. tn = gen->coeffs;
  2961. gen->phase += (gen->freq + fm);
  2962. cx = cos(x);
  2963. x2 = 2.0 * cx;
  2964. b = x2 * tn[3] + tn[2]; /* was -tn[2]! 19-Feb-14 */
  2965. return((x2 * b - tn[3] + tn[1]) * cx - b);
  2966. }
  2967. static mus_float_t polyw_first_5(mus_any *ptr, mus_float_t fm)
  2968. {
  2969. pw *gen = (pw *)ptr;
  2970. mus_float_t x;
  2971. mus_float_t *tn;
  2972. mus_float_t x2, b, b1, b2, cx;
  2973. x = gen->phase;
  2974. tn = gen->coeffs;
  2975. gen->phase += (gen->freq + fm);
  2976. cx = cos(x);
  2977. x2 = 2.0 * cx;
  2978. b1 = tn[4];
  2979. b = x2 * b1 + tn[3];
  2980. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2];
  2981. return((x2 * b - b1 + tn[1]) * cx - b);
  2982. }
  2983. static mus_float_t polyw_first_6(mus_any *ptr, mus_float_t fm)
  2984. {
  2985. pw *gen = (pw *)ptr;
  2986. mus_float_t x;
  2987. mus_float_t *tn;
  2988. mus_float_t x2, b, b1, b2, cx;
  2989. x = gen->phase;
  2990. tn = gen->coeffs;
  2991. gen->phase += (gen->freq + fm);
  2992. cx = cos(x);
  2993. x2 = 2.0 * cx;
  2994. b1 = tn[5];
  2995. b = x2 * b1 + tn[4];
  2996. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3];
  2997. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2];
  2998. return((x2 * b - b1 + tn[1]) * cx - b);
  2999. }
  3000. static mus_float_t polyw_first_8(mus_any *ptr, mus_float_t fm)
  3001. {
  3002. pw *gen = (pw *)ptr;
  3003. mus_float_t x;
  3004. mus_float_t *tn;
  3005. mus_float_t x2, b, b1, b2, cx;
  3006. x = gen->phase;
  3007. tn = gen->coeffs;
  3008. gen->phase += (gen->freq + fm);
  3009. cx = cos(x);
  3010. x2 = 2.0 * cx;
  3011. b1 = tn[7];
  3012. b = x2 * b1 + tn[6];
  3013. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[5];
  3014. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[4];
  3015. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3];
  3016. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2];
  3017. return((x2 * b - b1 + tn[1]) * cx - b);
  3018. }
  3019. static mus_float_t polyw_first_11(mus_any *ptr, mus_float_t fm)
  3020. {
  3021. pw *gen = (pw *)ptr;
  3022. mus_float_t x;
  3023. mus_float_t *tn;
  3024. mus_float_t x2, b, b1, b2, cx;
  3025. x = gen->phase;
  3026. tn = gen->coeffs;
  3027. gen->phase += (gen->freq + fm);
  3028. cx = cos(x);
  3029. x2 = 2.0 * cx;
  3030. b1 = tn[10];
  3031. b = x2 * b1 + tn[9];
  3032. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[8];
  3033. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[7];
  3034. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[6];
  3035. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[5];
  3036. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[4];
  3037. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[3];
  3038. b2 = b1; b1 = b; b = x2 * b1 - b2 + tn[2];
  3039. return((x2 * b - b1 + tn[1]) * cx - b);
  3040. }
  3041. static mus_float_t polyw_first(mus_any *ptr, mus_float_t fm)
  3042. {
  3043. pw *gen = (pw *)ptr;
  3044. mus_float_t ph;
  3045. ph = gen->phase;
  3046. gen->phase += (gen->freq + fm);
  3047. return(mus_chebyshev_t_sum_with_index(ph, gen->index, gen->n, gen->coeffs));
  3048. }
  3049. static mus_float_t polyw_f1(mus_any *ptr, mus_float_t fm)
  3050. {
  3051. pw *gen = (pw *)ptr;
  3052. mus_float_t cx;
  3053. cx = gen->index * cos(gen->phase);
  3054. gen->phase += (gen->freq + fm);
  3055. return(cx * gen->coeffs[1] + gen->coeffs[0]);
  3056. }
  3057. static mus_float_t polyw_f2(mus_any *ptr, mus_float_t fm)
  3058. {
  3059. pw *gen = (pw *)ptr;
  3060. mus_float_t ph;
  3061. ph = gen->phase;
  3062. gen->phase += (gen->freq + fm);
  3063. return(mus_chebyshev_t_sum_with_index_2(ph, gen->index, gen->n, gen->coeffs));
  3064. }
  3065. static mus_float_t polyw_f3(mus_any *ptr, mus_float_t fm)
  3066. {
  3067. pw *gen = (pw *)ptr;
  3068. mus_float_t ph;
  3069. ph = gen->phase;
  3070. gen->phase += (gen->freq + fm);
  3071. return(mus_chebyshev_t_sum_with_index_3(ph, gen->index, gen->n, gen->coeffs));
  3072. }
  3073. static mus_float_t polyw_f5(mus_any *ptr, mus_float_t fm)
  3074. {
  3075. pw *gen = (pw *)ptr;
  3076. mus_float_t ph;
  3077. ph = gen->phase;
  3078. gen->phase += (gen->freq + fm);
  3079. return(mus_chebyshev_t_sum_with_index_5(ph, gen->index, gen->n, gen->coeffs));
  3080. }
  3081. static mus_float_t polyw_second(mus_any *ptr, mus_float_t fm)
  3082. {
  3083. pw *gen = (pw *)ptr;
  3084. mus_float_t ph;
  3085. ph = gen->phase;
  3086. gen->phase += (gen->freq + fm);
  3087. return(mus_chebyshev_u_sum_with_index(ph, gen->index, gen->n, gen->coeffs));
  3088. }
  3089. static mus_float_t polyw_second_5(mus_any *ptr, mus_float_t fm)
  3090. {
  3091. pw *gen = (pw *)ptr;
  3092. mus_float_t *un;
  3093. mus_float_t x, b, b1, cx;
  3094. x = gen->phase;
  3095. gen->phase += (gen->freq + fm);
  3096. /* gen->n is 5 */
  3097. un = gen->coeffs;
  3098. /* this is a candidate for sincos, but gcc is already using it here! */
  3099. cx = 2.0 * cos(x);
  3100. b1 = cx * un[4] + un[3];
  3101. b = cx * b1 + gen->index;
  3102. return(sin(x) * (cx * b - b1 + un[1]));
  3103. }
  3104. static mus_float_t polyw_third(mus_any *ptr, mus_float_t fm)
  3105. {
  3106. pw *gen = (pw *)ptr;
  3107. mus_float_t ph;
  3108. ph = gen->phase;
  3109. gen->phase += (gen->freq + fm);
  3110. return(mus_chebyshev_tu_sum(ph, gen->n, gen->coeffs, gen->ucoeffs));
  3111. }
  3112. mus_float_t mus_polywave(mus_any *ptr, mus_float_t fm)
  3113. {
  3114. /* changed to use recursion, rather than polynomial in x, 25-May-08
  3115. * this algorithm taken from Mason and Handscomb, "Chebyshev Polynomials" p27
  3116. */
  3117. return((((pw *)ptr)->polyw)(ptr, fm));
  3118. }
  3119. mus_float_t mus_polywave_unmodulated(mus_any *ptr)
  3120. {
  3121. return(mus_polywave(ptr, 0.0));
  3122. }
  3123. static mus_float_t run_polywave(mus_any *ptr, mus_float_t fm, mus_float_t ignored) {return(mus_polywave(ptr, fm));}
  3124. static char *describe_polywave(mus_any *ptr)
  3125. {
  3126. pw *gen = (pw *)ptr;
  3127. char *str;
  3128. char *describe_buffer;
  3129. str = float_array_to_string(gen->coeffs, gen->n, 0);
  3130. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  3131. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, coeffs[%d]: %s",
  3132. mus_name(ptr),
  3133. mus_frequency(ptr),
  3134. mus_phase(ptr),
  3135. gen->n,
  3136. str);
  3137. free(str);
  3138. return(describe_buffer);
  3139. }
  3140. static mus_float_t pw_set_index_and_func(mus_any *ptr, mus_float_t val)
  3141. {
  3142. pw *gen = (pw *)ptr;
  3143. gen->index = val;
  3144. if (gen->cheby_choice == MUS_CHEBYSHEV_FIRST_KIND)
  3145. gen->polyw = polyw_first;
  3146. else gen->polyw = polyw_second;
  3147. return(val);
  3148. }
  3149. static mus_any_class POLYWAVE_CLASS = {
  3150. MUS_POLYWAVE,
  3151. (char *)S_polywave,
  3152. &free_pw,
  3153. &describe_polywave,
  3154. &pw_equalp,
  3155. &pw_data,
  3156. &pw_set_data,
  3157. &pw_n,
  3158. &pw_set_n,
  3159. &pw_freq,
  3160. &pw_set_freq,
  3161. &pw_phase,
  3162. &pw_set_phase,
  3163. &pw_index,
  3164. &pw_set_index_and_func,
  3165. &pw_increment,
  3166. &pw_set_increment,
  3167. &run_polywave,
  3168. MUS_NOT_SPECIAL,
  3169. NULL, 0,
  3170. 0, 0, 0, 0,
  3171. &pw_xcoeff, &pw_set_xcoeff,
  3172. 0, 0, 0, 0,
  3173. 0, 0, 0, 0, 0, 0,
  3174. &pw_choice,
  3175. &pw_ycoeff, &pw_set_ycoeff,
  3176. &pw_data, &pw_udata,
  3177. &pw_reset,
  3178. 0, &pw_copy
  3179. };
  3180. mus_any *mus_make_polywave(mus_float_t frequency, mus_float_t *coeffs, int n, int cheby_choice)
  3181. {
  3182. pw *gen;
  3183. gen = (pw *)malloc(sizeof(pw));
  3184. gen->core = &POLYWAVE_CLASS;
  3185. gen->phase = 0.0; /* cos used in cheby funcs above */
  3186. gen->freq = mus_hz_to_radians(frequency);
  3187. gen->coeffs = coeffs;
  3188. gen->ucoeffs = NULL;
  3189. gen->n = n;
  3190. gen->index = 1.0;
  3191. gen->cheby_choice = cheby_choice;
  3192. if (cheby_choice != MUS_CHEBYSHEV_SECOND_KIND)
  3193. {
  3194. if (coeffs[0] == 0.0)
  3195. {
  3196. /* these also ignore gen->index (assumed to be 1.0) (leaving aside the first_1 case)
  3197. * pw_set_index_and_func protects against that case
  3198. */
  3199. if (n == 2)
  3200. {
  3201. gen->polyw = polyw_first_1;
  3202. gen->index = coeffs[1];
  3203. }
  3204. else
  3205. {
  3206. if (n == 3)
  3207. gen->polyw = polyw_first_3;
  3208. else
  3209. {
  3210. if (n == 4)
  3211. gen->polyw = polyw_first_4;
  3212. else
  3213. {
  3214. if (n == 5)
  3215. gen->polyw = polyw_first_5;
  3216. else
  3217. {
  3218. if (n == 6)
  3219. gen->polyw = polyw_first_6;
  3220. else
  3221. {
  3222. if (n == 8)
  3223. gen->polyw = polyw_first_8;
  3224. else
  3225. {
  3226. if (n == 11) /* a common case oddly enough */
  3227. gen->polyw = polyw_first_11;
  3228. else
  3229. {
  3230. if (((n - 1) % 5) == 0)
  3231. gen->polyw = polyw_f5;
  3232. else
  3233. {
  3234. if (((n - 1) % 3) == 0)
  3235. gen->polyw = polyw_f3;
  3236. else
  3237. {
  3238. if (((n - 1) % 2) == 0)
  3239. gen->polyw = polyw_f2;
  3240. else
  3241. {
  3242. /* lots of n=8 here */
  3243. gen->polyw = polyw_first;
  3244. }
  3245. }
  3246. }
  3247. }
  3248. }
  3249. }
  3250. }
  3251. }
  3252. }
  3253. }
  3254. }
  3255. else
  3256. {
  3257. if (n == 2)
  3258. gen->polyw = polyw_f1;
  3259. else
  3260. {
  3261. if (((n - 1) % 3) == 0)
  3262. gen->polyw = polyw_f3;
  3263. else
  3264. {
  3265. if (((n - 1) % 2) == 0)
  3266. gen->polyw = polyw_f2;
  3267. else gen->polyw = polyw_first;
  3268. }
  3269. }
  3270. }
  3271. }
  3272. else
  3273. {
  3274. if ((n == 5) &&
  3275. (coeffs[0] == 0.0))
  3276. {
  3277. gen->polyw = polyw_second_5;
  3278. gen->index = coeffs[2] - coeffs[4];
  3279. }
  3280. else
  3281. {
  3282. if (n == 2)
  3283. gen->polyw = polyw_second_2;
  3284. else gen->polyw = polyw_second;
  3285. }
  3286. }
  3287. return((mus_any *)gen);
  3288. }
  3289. mus_any *mus_make_polywave_tu(mus_float_t frequency, mus_float_t *tcoeffs, mus_float_t *ucoeffs, int n)
  3290. {
  3291. pw *gen;
  3292. gen = (pw *)malloc(sizeof(pw));
  3293. gen->core = &POLYWAVE_CLASS;
  3294. gen->phase = 0.0; /* cos used in cheby funcs above */
  3295. gen->freq = mus_hz_to_radians(frequency);
  3296. gen->coeffs = tcoeffs;
  3297. gen->ucoeffs = ucoeffs;
  3298. gen->n = n;
  3299. gen->index = 1.0;
  3300. gen->cheby_choice = MUS_CHEBYSHEV_BOTH_KINDS;
  3301. gen->polyw = polyw_third;
  3302. return((mus_any *)gen);
  3303. }
  3304. bool mus_is_polywave(mus_any *ptr)
  3305. {
  3306. return((ptr) &&
  3307. (ptr->core->type == MUS_POLYWAVE));
  3308. }
  3309. /* ---------------- polyshape ---------------- */
  3310. static char *describe_polyshape(mus_any *ptr)
  3311. {
  3312. pw *gen = (pw *)ptr;
  3313. char *str;
  3314. char *describe_buffer;
  3315. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  3316. str = float_array_to_string(gen->coeffs, gen->n, 0);
  3317. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, coeffs[%d]: %s",
  3318. mus_name(ptr),
  3319. mus_frequency(ptr),
  3320. mus_phase(ptr),
  3321. gen->n,
  3322. str);
  3323. free(str);
  3324. return(describe_buffer);
  3325. }
  3326. mus_float_t mus_polyshape(mus_any *ptr, mus_float_t index, mus_float_t fm)
  3327. {
  3328. pw *gen = (pw *)ptr;
  3329. mus_float_t result;
  3330. gen->index = index;
  3331. result = mus_polynomial(gen->coeffs,
  3332. index * cos(gen->phase),
  3333. gen->n);
  3334. if (gen->cheby_choice == MUS_CHEBYSHEV_SECOND_KIND)
  3335. result *= sin(gen->phase);
  3336. gen->phase += (gen->freq + fm);
  3337. return(result);
  3338. }
  3339. mus_float_t mus_polyshape_unmodulated(mus_any *ptr, mus_float_t index)
  3340. {
  3341. pw *gen = (pw *)ptr;
  3342. mus_float_t result;
  3343. gen->index = index;
  3344. result = mus_polynomial(gen->coeffs,
  3345. index * cos(gen->phase),
  3346. gen->n);
  3347. if (gen->cheby_choice == MUS_CHEBYSHEV_SECOND_KIND)
  3348. result *= sin(gen->phase);
  3349. gen->phase += gen->freq;
  3350. return(result);
  3351. }
  3352. static mus_any_class POLYSHAPE_CLASS = {
  3353. MUS_POLYSHAPE,
  3354. (char *)S_polyshape,
  3355. &free_pw,
  3356. &describe_polyshape,
  3357. &pw_equalp,
  3358. &pw_data,
  3359. &pw_set_data,
  3360. &pw_n,
  3361. &pw_set_n,
  3362. &pw_freq,
  3363. &pw_set_freq,
  3364. &pw_phase,
  3365. &pw_set_phase,
  3366. &pw_index, &pw_set_index,
  3367. &pw_increment,
  3368. &pw_set_increment,
  3369. &mus_polyshape,
  3370. MUS_NOT_SPECIAL,
  3371. NULL, 0,
  3372. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3373. 0, 0, 0, 0, 0, 0, 0,
  3374. 0, 0, 0, 0,
  3375. &pw_reset,
  3376. 0, &pw_copy
  3377. };
  3378. mus_any *mus_make_polyshape(mus_float_t frequency, mus_float_t phase, mus_float_t *coeffs, int size, int cheby_choice)
  3379. {
  3380. mus_any *gen;
  3381. gen = mus_make_polywave(frequency, coeffs, size, cheby_choice);
  3382. gen->core = &POLYSHAPE_CLASS;
  3383. pw_set_phase(gen, phase);
  3384. return(gen);
  3385. }
  3386. bool mus_is_polyshape(mus_any *ptr)
  3387. {
  3388. return((ptr) &&
  3389. (ptr->core->type == MUS_POLYSHAPE));
  3390. }
  3391. /* ---------------- wave-train ---------------- */
  3392. typedef struct {
  3393. mus_any_class *core;
  3394. mus_float_t freq, phase;
  3395. mus_float_t *wave; /* passed in from caller */
  3396. mus_long_t wave_size;
  3397. mus_float_t *out_data;
  3398. mus_long_t out_data_size;
  3399. mus_interp_t interp_type; /* "type" field exists in core -- avoid confusion */
  3400. mus_float_t next_wave_time;
  3401. mus_long_t out_pos;
  3402. bool first_time;
  3403. mus_float_t yn1;
  3404. } wt;
  3405. static mus_float_t wt_freq(mus_any *ptr) {return(((wt *)ptr)->freq);}
  3406. static mus_float_t wt_set_freq(mus_any *ptr, mus_float_t val) {((wt *)ptr)->freq = val; return(val);}
  3407. static mus_float_t wt_phase(mus_any *ptr) {return(fmod(((TWO_PI * ((wt *)ptr)->phase) / ((mus_float_t)((wt *)ptr)->wave_size)), TWO_PI));}
  3408. static mus_float_t wt_set_phase(mus_any *ptr, mus_float_t val) {((wt *)ptr)->phase = (fmod(val, TWO_PI) * ((wt *)ptr)->wave_size) / TWO_PI; return(val);}
  3409. static mus_long_t wt_length(mus_any *ptr) {return(((wt *)ptr)->wave_size);}
  3410. static mus_long_t wt_set_length(mus_any *ptr, mus_long_t val) {if (val > 0) ((wt *)ptr)->wave_size = val; return(((wt *)ptr)->wave_size);}
  3411. static int wt_interp_type(mus_any *ptr) {return((int)(((wt *)ptr)->interp_type));}
  3412. static mus_float_t *wt_data(mus_any *ptr) {return(((wt *)ptr)->wave);}
  3413. static mus_float_t *wt_set_data(mus_any *ptr, mus_float_t *data) {((wt *)ptr)->wave = data; return(data);}
  3414. static mus_any *wt_copy(mus_any *ptr)
  3415. {
  3416. wt *g, *p;
  3417. int bytes;
  3418. p = (wt *)ptr;
  3419. g = (wt *)malloc(sizeof(wt));
  3420. memcpy((void *)g, (void *)ptr, sizeof(wt));
  3421. bytes = g->out_data_size * sizeof(mus_float_t);
  3422. g->out_data = (mus_float_t *)malloc(bytes);
  3423. memcpy((void *)(g->out_data), (void *)(p->out_data), bytes);
  3424. /* g->wave is caller's data */
  3425. return((mus_any *)g);
  3426. }
  3427. static bool wt_equalp(mus_any *p1, mus_any *p2)
  3428. {
  3429. wt *w1 = (wt *)p1;
  3430. wt *w2 = (wt *)p2;
  3431. if (p1 == p2) return(true);
  3432. return((w1) && (w2) &&
  3433. (w1->core->type == w2->core->type) &&
  3434. (w1->freq == w2->freq) &&
  3435. (w1->phase == w2->phase) &&
  3436. (w1->interp_type == w2->interp_type) &&
  3437. (w1->wave_size == w2->wave_size) &&
  3438. (w1->out_data_size == w2->out_data_size) &&
  3439. (w1->out_pos == w2->out_pos) &&
  3440. (clm_arrays_are_equal(w1->wave, w2->wave, w1->wave_size)) &&
  3441. (clm_arrays_are_equal(w1->out_data, w2->out_data, w1->out_data_size)));
  3442. }
  3443. static char *describe_wt(mus_any *ptr)
  3444. {
  3445. char *describe_buffer;
  3446. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  3447. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, size: %lld, interp: %s",
  3448. mus_name(ptr),
  3449. mus_frequency(ptr),
  3450. mus_phase(ptr),
  3451. mus_length(ptr),
  3452. interp_type_to_string(wt_interp_type(ptr)));
  3453. return(describe_buffer);
  3454. }
  3455. static mus_float_t mus_wave_train_any(mus_any *ptr, mus_float_t fm)
  3456. {
  3457. wt *gen = (wt *)ptr;
  3458. mus_float_t result = 0.0;
  3459. if (gen->out_pos < gen->out_data_size)
  3460. result = gen->out_data[gen->out_pos];
  3461. gen->out_pos++;
  3462. if (gen->out_pos >= gen->next_wave_time)
  3463. {
  3464. mus_long_t i;
  3465. mus_float_t *wave, *out_data;
  3466. mus_long_t wave_size;
  3467. wave = gen->wave;
  3468. wave_size = gen->wave_size;
  3469. out_data = gen->out_data;
  3470. if (gen->out_pos < gen->out_data_size)
  3471. {
  3472. mus_long_t good_samps;
  3473. good_samps = gen->out_data_size - gen->out_pos;
  3474. memmove((void *)out_data, (void *)(out_data + gen->out_pos), good_samps * sizeof(mus_float_t));
  3475. memset((void *)(out_data + good_samps), 0, gen->out_pos * sizeof(mus_float_t));
  3476. }
  3477. else memset((void *)out_data, 0, gen->out_data_size * sizeof(mus_float_t));
  3478. if (gen->interp_type == MUS_INTERP_LINEAR)
  3479. {
  3480. /* gen->phase doesn't change, and i is an int, so we can precalculate the fractional part, etc
  3481. */
  3482. mus_float_t phase, frac_part;
  3483. mus_long_t int_part;
  3484. phase = gen->phase;
  3485. if ((phase < 0.0) || (phase > wave_size))
  3486. {
  3487. phase = fmod((mus_float_t)phase, (mus_float_t)wave_size);
  3488. if (phase < 0.0) phase += wave_size;
  3489. }
  3490. int_part = (mus_long_t)floor(phase);
  3491. frac_part = phase - int_part;
  3492. if (int_part == wave_size) int_part = 0;
  3493. if (frac_part == 0.0)
  3494. {
  3495. mus_long_t p;
  3496. for (i = 0, p = int_part; i < wave_size; i++, p++)
  3497. {
  3498. if (p == wave_size) p = 0;
  3499. out_data[i] += wave[p];
  3500. }
  3501. }
  3502. else
  3503. {
  3504. mus_long_t p, p1;
  3505. for (i = 0, p = int_part, p1 = int_part + 1; i < wave_size; i++, p1++)
  3506. {
  3507. if (p1 == wave_size) p1 = 0;
  3508. out_data[i] += (wave[p] + frac_part * (wave[p1] - wave[p]));
  3509. p = p1;
  3510. }
  3511. }
  3512. }
  3513. else
  3514. {
  3515. for (i = 0; i < wave_size; i++)
  3516. {
  3517. gen->yn1 = mus_interpolate(gen->interp_type, gen->phase + i, wave, wave_size, gen->yn1);
  3518. out_data[i] += gen->yn1;
  3519. }
  3520. }
  3521. if (gen->first_time)
  3522. {
  3523. gen->first_time = false;
  3524. gen->out_pos = (mus_long_t)(gen->phase); /* initial phase, but as an integer in terms of wave table size (gad...) */
  3525. if (gen->out_pos >= wave_size)
  3526. gen->out_pos = gen->out_pos % wave_size;
  3527. result = out_data[gen->out_pos++];
  3528. gen->next_wave_time = ((mus_float_t)sampling_rate / (gen->freq + fm));
  3529. }
  3530. else
  3531. {
  3532. gen->next_wave_time += (((mus_float_t)sampling_rate / (gen->freq + fm)) - gen->out_pos);
  3533. gen->out_pos = 0;
  3534. }
  3535. }
  3536. return(result);
  3537. }
  3538. mus_float_t mus_wave_train(mus_any *ptr, mus_float_t fm) {return(mus_wave_train_any(ptr, fm / w_rate));}
  3539. mus_float_t mus_wave_train_unmodulated(mus_any *ptr) {return(mus_wave_train(ptr, 0.0));}
  3540. static mus_float_t run_wave_train(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_wave_train_any(ptr, fm / w_rate));}
  3541. static void free_wt(mus_any *p)
  3542. {
  3543. wt *ptr = (wt *)p;
  3544. if (ptr->out_data)
  3545. {
  3546. free(ptr->out_data);
  3547. ptr->out_data = NULL;
  3548. }
  3549. free(ptr);
  3550. }
  3551. static void wt_reset(mus_any *ptr)
  3552. {
  3553. wt *gen = (wt *)ptr;
  3554. gen->phase = 0.0;
  3555. memset((void *)(gen->out_data), 0, gen->out_data_size * sizeof(mus_float_t));
  3556. gen->out_pos = gen->out_data_size;
  3557. gen->next_wave_time = 0.0;
  3558. gen->first_time = true;
  3559. }
  3560. static mus_any_class WAVE_TRAIN_CLASS = {
  3561. MUS_WAVE_TRAIN,
  3562. (char *)S_wave_train,
  3563. &free_wt,
  3564. &describe_wt,
  3565. &wt_equalp,
  3566. &wt_data,
  3567. &wt_set_data,
  3568. &wt_length,
  3569. &wt_set_length,
  3570. &wt_freq,
  3571. &wt_set_freq,
  3572. &wt_phase,
  3573. &wt_set_phase,
  3574. &fallback_scaler, 0,
  3575. 0, 0,
  3576. &run_wave_train,
  3577. MUS_NOT_SPECIAL,
  3578. NULL,
  3579. &wt_interp_type,
  3580. 0, 0,
  3581. 0, 0, 0, 0, 0, 0, 0, 0,
  3582. 0, 0, 0, 0, 0, 0, 0,
  3583. 0, 0, 0, 0,
  3584. &wt_reset,
  3585. 0, &wt_copy
  3586. };
  3587. mus_any *mus_make_wave_train(mus_float_t freq, mus_float_t phase, mus_float_t *wave, mus_long_t wave_size, mus_interp_t type)
  3588. {
  3589. wt *gen;
  3590. gen = (wt *)malloc(sizeof(wt));
  3591. gen->core = &WAVE_TRAIN_CLASS;
  3592. gen->freq = freq;
  3593. gen->phase = (wave_size * fmod(phase, TWO_PI)) / TWO_PI;
  3594. gen->wave = wave;
  3595. gen->wave_size = wave_size;
  3596. gen->interp_type = type;
  3597. gen->out_data_size = wave_size + 2;
  3598. gen->out_data = (mus_float_t *)calloc(gen->out_data_size, sizeof(mus_float_t));
  3599. gen->out_pos = gen->out_data_size;
  3600. gen->next_wave_time = 0.0;
  3601. gen->first_time = true;
  3602. gen->yn1 = 0.0;
  3603. return((mus_any *)gen);
  3604. }
  3605. bool mus_is_wave_train(mus_any *ptr)
  3606. {
  3607. return((ptr) &&
  3608. (ptr->core->type == MUS_WAVE_TRAIN));
  3609. }
  3610. /* ---------------- delay, comb, notch, all-pass, moving-average, filtered-comb ---------------- */
  3611. typedef struct dly {
  3612. mus_any_class *core;
  3613. unsigned int loc, size;
  3614. bool zdly, line_allocated, filt_allocated;
  3615. mus_float_t *line;
  3616. unsigned int zloc, zsize;
  3617. mus_float_t xscl, yscl, yn1, y1, norm;
  3618. mus_interp_t type;
  3619. mus_any *filt;
  3620. struct dly *next;
  3621. mus_float_t (*runf)(mus_any *gen, mus_float_t arg1, mus_float_t arg2);
  3622. mus_float_t (*del)(mus_any *ptr, mus_float_t input); /* zdelay or normal tap */
  3623. mus_float_t (*delt)(mus_any *ptr, mus_float_t input); /* just tick */
  3624. mus_float_t (*delu)(mus_any *ptr, mus_float_t input); /* unmodulated */
  3625. } dly;
  3626. mus_float_t mus_delay_tick(mus_any *ptr, mus_float_t input)
  3627. {
  3628. return(((dly *)ptr)->delt(ptr, input));
  3629. }
  3630. mus_float_t mus_tap(mus_any *ptr, mus_float_t loc)
  3631. {
  3632. return(((dly *)ptr)->del(ptr, loc));
  3633. }
  3634. mus_float_t mus_delay_unmodulated(mus_any *ptr, mus_float_t input)
  3635. {
  3636. return(((dly *)ptr)->delu(ptr, input));
  3637. }
  3638. static mus_float_t ztap(mus_any *ptr, mus_float_t loc)
  3639. {
  3640. dly *gen = (dly *)ptr;
  3641. /* this is almost always linear */
  3642. if (gen->type == MUS_INTERP_LINEAR)
  3643. return(mus_array_interp(gen->line, gen->zloc - loc, gen->zsize));
  3644. gen->yn1 = mus_interpolate(gen->type, gen->zloc - loc, gen->line, gen->zsize, gen->yn1);
  3645. return(gen->yn1);
  3646. }
  3647. static mus_float_t dtap(mus_any *ptr, mus_float_t loc)
  3648. {
  3649. dly *gen = (dly *)ptr;
  3650. int taploc;
  3651. if (gen->size == 0) return(gen->line[0]);
  3652. if ((int)loc == 0) return(gen->line[gen->loc]);
  3653. taploc = (int)(gen->loc - (int)loc) % gen->size;
  3654. if (taploc < 0) taploc += gen->size;
  3655. return(gen->line[taploc]);
  3656. }
  3657. mus_float_t mus_tap_unmodulated(mus_any *ptr)
  3658. {
  3659. dly *gen = (dly *)ptr;
  3660. return(gen->line[gen->loc]);
  3661. }
  3662. static mus_float_t zdelt(mus_any *ptr, mus_float_t input)
  3663. {
  3664. dly *gen = (dly *)ptr;
  3665. gen->line[gen->loc] = input;
  3666. gen->loc++;
  3667. if (gen->loc >= gen->zsize) gen->loc = 0;
  3668. gen->zloc++;
  3669. if (gen->zloc >= gen->zsize) gen->zloc = 0;
  3670. return(input);
  3671. }
  3672. static mus_float_t delt(mus_any *ptr, mus_float_t input)
  3673. {
  3674. dly *gen = (dly *)ptr;
  3675. gen->line[gen->loc] = input;
  3676. gen->loc++;
  3677. if (gen->loc >= gen->size) gen->loc = 0;
  3678. return(input);
  3679. }
  3680. mus_float_t mus_delay(mus_any *ptr, mus_float_t input, mus_float_t pm)
  3681. {
  3682. mus_float_t result;
  3683. dly *gen = (dly *)ptr;
  3684. if ((gen->size == 0) && (pm < 1.0))
  3685. result = pm * gen->line[0] + (1.0 - pm) * input;
  3686. else result = mus_tap(ptr, pm);
  3687. mus_delay_tick(ptr, input);
  3688. return(result);
  3689. }
  3690. static mus_float_t zdelay_unmodulated(mus_any *ptr, mus_float_t input)
  3691. {
  3692. dly *gen = (dly *)ptr;
  3693. mus_float_t result;
  3694. result = gen->line[gen->zloc];
  3695. mus_delay_tick(ptr, input);
  3696. return(result);
  3697. }
  3698. static mus_float_t delay_unmodulated_zero(mus_any *ptr, mus_float_t input)
  3699. {
  3700. return(input);
  3701. }
  3702. mus_float_t mus_delay_unmodulated_noz(mus_any *ptr, mus_float_t input)
  3703. {
  3704. dly *gen = (dly *)ptr;
  3705. mus_float_t result;
  3706. result = gen->line[gen->loc];
  3707. gen->line[gen->loc] = input;
  3708. gen->loc++;
  3709. if (gen->loc >= gen->size)
  3710. gen->loc = 0;
  3711. return(result);
  3712. }
  3713. static dly *dly_free_list = NULL;
  3714. static void free_delay(mus_any *gen)
  3715. {
  3716. dly *ptr = (dly *)gen;
  3717. if ((ptr->line) && (ptr->line_allocated)) free(ptr->line);
  3718. if ((ptr->filt) && (ptr->filt_allocated)) mus_free(ptr->filt);
  3719. /* free(ptr); */
  3720. ptr->next = dly_free_list;
  3721. dly_free_list = ptr;
  3722. }
  3723. static mus_any *dly_copy(mus_any *ptr)
  3724. {
  3725. dly *g, *p;
  3726. mus_long_t bytes;
  3727. p = (dly *)ptr;
  3728. if (dly_free_list)
  3729. {
  3730. g = dly_free_list;
  3731. dly_free_list = g->next;
  3732. }
  3733. else g = (dly *)malloc(sizeof(dly));
  3734. memcpy((void *)g, (void *)ptr, sizeof(dly));
  3735. bytes = g->size * sizeof(mus_float_t);
  3736. g->line = (mus_float_t *)malloc(bytes);
  3737. memcpy((void *)(g->line), (void *)(p->line), bytes);
  3738. g->line_allocated = true;
  3739. if (p->filt)
  3740. {
  3741. g->filt = mus_copy(p->filt);
  3742. g->filt_allocated = true;
  3743. }
  3744. return((mus_any *)g);
  3745. }
  3746. static char *describe_delay(mus_any *ptr)
  3747. {
  3748. char *str = NULL;
  3749. dly *gen = (dly *)ptr;
  3750. char *describe_buffer;
  3751. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  3752. if (gen->zdly)
  3753. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s line[%u,%u, %s]: %s",
  3754. mus_name(ptr),
  3755. gen->size,
  3756. gen->zsize,
  3757. interp_type_to_string(gen->type),
  3758. str = float_array_to_string(gen->line, gen->size, gen->zloc));
  3759. else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s line[%u, %s]: %s",
  3760. mus_name(ptr),
  3761. gen->size,
  3762. interp_type_to_string(gen->type),
  3763. str = float_array_to_string(gen->line, gen->size, gen->loc));
  3764. if (str) free(str);
  3765. return(describe_buffer);
  3766. }
  3767. static bool delay_equalp(mus_any *p1, mus_any *p2)
  3768. {
  3769. dly *d1 = (dly *)p1;
  3770. dly *d2 = (dly *)p2;
  3771. if (p1 == p2) return(true);
  3772. return((d1) && (d2) &&
  3773. (d1->core->type == d2->core->type) &&
  3774. (d1->size == d2->size) &&
  3775. (d1->loc == d2->loc) &&
  3776. (d1->zdly == d2->zdly) &&
  3777. (d1->zloc == d2->zloc) &&
  3778. (d1->zsize == d2->zsize) &&
  3779. (d1->xscl == d2->xscl) &&
  3780. (d1->yscl == d2->yscl) &&
  3781. (d1->yn1 == d2->yn1) &&
  3782. (d1->type == d2->type) &&
  3783. (clm_arrays_are_equal(d1->line, d2->line, d1->size)));
  3784. }
  3785. static mus_long_t delay_length(mus_any *ptr)
  3786. {
  3787. dly *d = (dly *)ptr;
  3788. if (d->size > 0) /* this is possible (not sure it's a good idea...) */
  3789. return(d->size);
  3790. return(d->zsize); /* maybe always use this? */
  3791. }
  3792. static mus_float_t delay_scaler(mus_any *ptr) {return(((dly *)ptr)->xscl);}
  3793. static mus_float_t delay_set_scaler(mus_any *ptr, mus_float_t val) {((dly *)ptr)->xscl = val; return(val);}
  3794. static mus_float_t delay_fb(mus_any *ptr) {return(((dly *)ptr)->yscl);}
  3795. static mus_float_t delay_set_fb(mus_any *ptr, mus_float_t val) {((dly *)ptr)->yscl = val; return(val);}
  3796. static int delay_interp_type(mus_any *ptr) {return((int)(((dly *)ptr)->type));}
  3797. static mus_long_t delay_loc(mus_any *ptr){return((mus_long_t)(((dly *)ptr)->loc));}
  3798. static mus_float_t *delay_data(mus_any *ptr) {return(((dly *)ptr)->line);}
  3799. static mus_float_t *delay_set_data(mus_any *ptr, mus_float_t *val)
  3800. {
  3801. dly *gen = (dly *)ptr;
  3802. if (gen->line_allocated) {free(gen->line); gen->line_allocated = false;}
  3803. gen->line = val;
  3804. return(val);
  3805. }
  3806. static mus_long_t delay_set_length(mus_any *ptr, mus_long_t val)
  3807. {
  3808. dly *gen = (dly *)ptr;
  3809. if (val > 0)
  3810. {
  3811. unsigned int old_size;
  3812. old_size = gen->size;
  3813. gen->size = (unsigned int)val;
  3814. if (gen->size < old_size)
  3815. {
  3816. if (gen->loc > gen->size) gen->loc = 0;
  3817. gen->zdly = false; /* otherwise too many ways to screw up */
  3818. }
  3819. }
  3820. return((mus_long_t)(gen->size));
  3821. }
  3822. bool mus_is_tap(mus_any *gen)
  3823. {
  3824. return((gen) &&
  3825. (gen->core->extended_type == MUS_DELAY_LINE));
  3826. }
  3827. static void delay_reset(mus_any *ptr)
  3828. {
  3829. dly *gen = (dly *)ptr;
  3830. gen->loc = 0;
  3831. gen->zloc = 0;
  3832. gen->yn1 = 0.0;
  3833. memset((void *)(gen->line), 0, gen->zsize * sizeof(mus_float_t));
  3834. }
  3835. static mus_any_class DELAY_CLASS = {
  3836. MUS_DELAY,
  3837. (char *)S_delay,
  3838. &free_delay,
  3839. &describe_delay,
  3840. &delay_equalp,
  3841. &delay_data,
  3842. &delay_set_data,
  3843. &delay_length,
  3844. &delay_set_length,
  3845. 0, 0, 0, 0, /* freq phase */
  3846. &delay_scaler,
  3847. &delay_set_scaler,
  3848. &delay_fb,
  3849. &delay_set_fb,
  3850. &mus_delay,
  3851. MUS_DELAY_LINE,
  3852. NULL,
  3853. &delay_interp_type,
  3854. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3855. 0, 0, 0, 0,
  3856. &delay_loc,
  3857. 0, 0,
  3858. 0, 0, 0, 0,
  3859. &delay_reset,
  3860. 0, &dly_copy
  3861. };
  3862. mus_any *mus_make_delay(int size, mus_float_t *preloaded_line, int line_size, mus_interp_t type)
  3863. {
  3864. /* if preloaded_line null, allocated locally.
  3865. * if size == line_size, normal (non-interpolating) delay
  3866. * in clm2xen.c, if size=0 and max-size unset, max-size=1 (line_size here)
  3867. */
  3868. dly *gen;
  3869. if (dly_free_list)
  3870. {
  3871. gen = dly_free_list;
  3872. dly_free_list = gen->next;
  3873. }
  3874. else gen = (dly *)malloc(sizeof(dly));
  3875. gen->core = &DELAY_CLASS;
  3876. gen->loc = 0;
  3877. gen->size = size;
  3878. gen->zsize = line_size;
  3879. gen->zdly = ((line_size != size) || (type != MUS_INTERP_NONE));
  3880. if (gen->zdly)
  3881. {
  3882. gen->del = ztap;
  3883. gen->delt = zdelt;
  3884. if (gen->size == 0)
  3885. gen->delu = delay_unmodulated_zero;
  3886. else gen->delu = zdelay_unmodulated;
  3887. }
  3888. else
  3889. {
  3890. gen->del = dtap;
  3891. gen->delt = delt;
  3892. if (gen->size == 0)
  3893. gen->delu = delay_unmodulated_zero;
  3894. else gen->delu = mus_delay_unmodulated_noz;
  3895. }
  3896. gen->type = type;
  3897. if (preloaded_line)
  3898. {
  3899. gen->line = preloaded_line;
  3900. gen->line_allocated = false;
  3901. }
  3902. else
  3903. {
  3904. gen->line = (mus_float_t *)calloc((line_size <= 0) ? 1 : line_size, sizeof(mus_float_t));
  3905. gen->line_allocated = true;
  3906. }
  3907. gen->zloc = line_size - size;
  3908. gen->filt = NULL;
  3909. gen->filt_allocated = false;
  3910. gen->xscl = 0.0;
  3911. gen->yscl = 0.0;
  3912. gen->yn1 = 0.0;
  3913. gen->runf = NULL;
  3914. return((mus_any *)gen);
  3915. }
  3916. bool mus_is_delay(mus_any *ptr)
  3917. {
  3918. return((ptr) &&
  3919. (ptr->core->type == MUS_DELAY));
  3920. }
  3921. /* ---------------- comb ---------------- */
  3922. mus_float_t mus_comb(mus_any *ptr, mus_float_t input, mus_float_t pm)
  3923. {
  3924. dly *gen = (dly *)ptr;
  3925. if (gen->zdly)
  3926. return(mus_delay(ptr, input + (gen->yscl * mus_tap(ptr, pm)), pm));
  3927. /* mus.lisp has 0 in place of the final pm -- the question is whether the delay
  3928. should interpolate as well as the tap. There is a subtle difference in
  3929. output (the pm case is low-passed by the interpolation ("average")),
  3930. but I don't know if there's a standard here, or what people expect.
  3931. We're doing the outer-level interpolation in notch and all-pass.
  3932. Should mus.lisp be changed?
  3933. */
  3934. else return(mus_delay_unmodulated(ptr, input + (gen->line[gen->loc] * gen->yscl)));
  3935. }
  3936. mus_float_t mus_comb_unmodulated(mus_any *ptr, mus_float_t input)
  3937. {
  3938. dly *gen = (dly *)ptr;
  3939. if (gen->zdly)
  3940. return(mus_delay_unmodulated(ptr, input + (gen->line[gen->zloc] * gen->yscl)));
  3941. return(mus_delay_unmodulated(ptr, input + (gen->line[gen->loc] * gen->yscl)));
  3942. }
  3943. mus_float_t mus_comb_unmodulated_noz(mus_any *ptr, mus_float_t input)
  3944. {
  3945. dly *gen = (dly *)ptr;
  3946. mus_float_t result;
  3947. result = gen->line[gen->loc];
  3948. gen->line[gen->loc] = input + (result * gen->yscl);
  3949. gen->loc++;
  3950. if (gen->loc >= gen->size)
  3951. gen->loc = 0;
  3952. return(result);
  3953. }
  3954. static char *describe_comb(mus_any *ptr)
  3955. {
  3956. char *str = NULL;
  3957. dly *gen = (dly *)ptr;
  3958. char *describe_buffer;
  3959. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  3960. if (gen->zdly)
  3961. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u,%u, %s]: %s",
  3962. mus_name(ptr),
  3963. gen->yscl,
  3964. gen->size,
  3965. gen->zsize,
  3966. interp_type_to_string(gen->type),
  3967. str = float_array_to_string(gen->line, gen->size, gen->zloc));
  3968. else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u, %s]: %s",
  3969. mus_name(ptr),
  3970. gen->yscl,
  3971. gen->size,
  3972. interp_type_to_string(gen->type),
  3973. str = float_array_to_string(gen->line, gen->size, gen->loc));
  3974. if (str) free(str);
  3975. return(describe_buffer);
  3976. }
  3977. static mus_any_class COMB_CLASS = {
  3978. MUS_COMB,
  3979. (char *)S_comb,
  3980. &free_delay,
  3981. &describe_comb,
  3982. &delay_equalp,
  3983. &delay_data,
  3984. &delay_set_data,
  3985. &delay_length,
  3986. &delay_set_length,
  3987. 0, 0, 0, 0, /* freq phase */
  3988. &delay_scaler,
  3989. &delay_set_scaler,
  3990. &delay_fb,
  3991. &delay_set_fb,
  3992. &mus_comb,
  3993. MUS_DELAY_LINE,
  3994. NULL,
  3995. &delay_interp_type,
  3996. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  3997. 0, 0, 0, 0,
  3998. &delay_loc,
  3999. 0, 0,
  4000. 0, 0, 0, 0,
  4001. &delay_reset,
  4002. 0, &dly_copy
  4003. };
  4004. mus_any *mus_make_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type)
  4005. {
  4006. dly *gen;
  4007. gen = (dly *)mus_make_delay(size, line, line_size, type);
  4008. if (gen)
  4009. {
  4010. gen->core = &COMB_CLASS;
  4011. gen->yscl = scaler;
  4012. return((mus_any *)gen);
  4013. }
  4014. return(NULL);
  4015. }
  4016. bool mus_is_comb(mus_any *ptr)
  4017. {
  4018. return((ptr) &&
  4019. (ptr->core->type == MUS_COMB));
  4020. }
  4021. /* ---------------- comb-bank ---------------- */
  4022. typedef struct {
  4023. mus_any_class *core;
  4024. int size;
  4025. mus_any **gens;
  4026. mus_float_t (*cmbf)(mus_any *ptr, mus_float_t input);
  4027. } cmb_bank;
  4028. static void free_comb_bank(mus_any *ptr)
  4029. {
  4030. cmb_bank *f = (cmb_bank *)ptr;
  4031. if (f->gens) {free(f->gens); f->gens = NULL;}
  4032. free(ptr);
  4033. }
  4034. static mus_any *cmb_bank_copy(mus_any *ptr)
  4035. {
  4036. cmb_bank *g, *p;
  4037. int i;
  4038. p = (cmb_bank *)ptr;
  4039. g = (cmb_bank *)malloc(sizeof(cmb_bank));
  4040. memcpy((void *)g, (void *)ptr, sizeof(cmb_bank));
  4041. g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *));
  4042. for (i = 0; i < p->size; i++)
  4043. g->gens[i] = mus_copy(p->gens[i]);
  4044. return((mus_any *)g);
  4045. }
  4046. static mus_float_t run_comb_bank(mus_any *ptr, mus_float_t input, mus_float_t unused)
  4047. {
  4048. return(mus_comb_bank(ptr, input));
  4049. }
  4050. static mus_long_t comb_bank_length(mus_any *ptr)
  4051. {
  4052. return(((cmb_bank *)ptr)->size);
  4053. }
  4054. static void comb_bank_reset(mus_any *ptr)
  4055. {
  4056. cmb_bank *f = (cmb_bank *)ptr;
  4057. int i;
  4058. for (i = 0; i < f->size; i++)
  4059. mus_reset(f->gens[i]);
  4060. }
  4061. static bool comb_bank_equalp(mus_any *p1, mus_any *p2)
  4062. {
  4063. cmb_bank *f1 = (cmb_bank *)p1;
  4064. cmb_bank *f2 = (cmb_bank *)p2;
  4065. int i, size;
  4066. if (f1 == f2) return(true);
  4067. if (f1->size != f2->size) return(false);
  4068. size = f1->size;
  4069. for (i = 0; i < size; i++)
  4070. if (!delay_equalp(f1->gens[i], f2->gens[i]))
  4071. return(false);
  4072. /* now check the locals... */
  4073. return(true);
  4074. }
  4075. static char *describe_comb_bank(mus_any *ptr)
  4076. {
  4077. cmb_bank *gen = (cmb_bank *)ptr;
  4078. char *describe_buffer;
  4079. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4080. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d",
  4081. mus_name(ptr),
  4082. gen->size);
  4083. return(describe_buffer);
  4084. }
  4085. static mus_any_class COMB_BANK_CLASS = {
  4086. MUS_COMB_BANK,
  4087. (char *)S_comb_bank,
  4088. &free_comb_bank,
  4089. &describe_comb_bank,
  4090. &comb_bank_equalp,
  4091. 0, 0,
  4092. &comb_bank_length, 0,
  4093. 0, 0,
  4094. 0, 0,
  4095. 0, 0,
  4096. 0, 0,
  4097. &run_comb_bank,
  4098. MUS_NOT_SPECIAL,
  4099. NULL, 0,
  4100. 0, 0, 0, 0,
  4101. 0, 0,
  4102. 0, 0, 0, 0,
  4103. 0, 0, 0, 0, 0, 0, 0,
  4104. 0, 0, 0, 0,
  4105. &comb_bank_reset,
  4106. 0, &cmb_bank_copy
  4107. };
  4108. static mus_float_t comb_bank_any(mus_any *combs, mus_float_t inval)
  4109. {
  4110. int i;
  4111. mus_float_t sum = 0.0;
  4112. cmb_bank *c = (cmb_bank *)combs;
  4113. for (i = 0; i < c->size; i++)
  4114. sum += mus_comb_unmodulated_noz(c->gens[i], inval);
  4115. return(sum);
  4116. }
  4117. static mus_float_t comb_bank_4(mus_any *combs, mus_float_t inval)
  4118. {
  4119. cmb_bank *c = (cmb_bank *)combs;
  4120. mus_any **gs;
  4121. gs = c->gens;
  4122. return(mus_comb_unmodulated_noz(gs[0], inval) +
  4123. mus_comb_unmodulated_noz(gs[1], inval) +
  4124. mus_comb_unmodulated_noz(gs[2], inval) +
  4125. mus_comb_unmodulated_noz(gs[3], inval));
  4126. }
  4127. static mus_float_t comb_bank_6(mus_any *combs, mus_float_t inval)
  4128. {
  4129. cmb_bank *c = (cmb_bank *)combs;
  4130. mus_any **gs;
  4131. gs = c->gens;
  4132. return(mus_comb_unmodulated_noz(gs[0], inval) +
  4133. mus_comb_unmodulated_noz(gs[1], inval) +
  4134. mus_comb_unmodulated_noz(gs[2], inval) +
  4135. mus_comb_unmodulated_noz(gs[3], inval) +
  4136. mus_comb_unmodulated_noz(gs[4], inval) +
  4137. mus_comb_unmodulated_noz(gs[5], inval));
  4138. }
  4139. mus_any *mus_make_comb_bank(int size, mus_any **combs)
  4140. {
  4141. cmb_bank *gen;
  4142. int i;
  4143. gen = (cmb_bank *)malloc(sizeof(cmb_bank));
  4144. gen->core = &COMB_BANK_CLASS;
  4145. gen->size = size;
  4146. gen->gens = (mus_any **)malloc(size * sizeof(mus_any *));
  4147. for (i = 0; i < size; i++)
  4148. gen->gens[i] = combs[i];
  4149. if (size == 4)
  4150. gen->cmbf = comb_bank_4;
  4151. else
  4152. {
  4153. if (size == 6)
  4154. gen->cmbf = comb_bank_6;
  4155. else gen->cmbf = comb_bank_any;
  4156. }
  4157. return((mus_any *)gen);
  4158. }
  4159. bool mus_is_comb_bank(mus_any *ptr)
  4160. {
  4161. return((ptr) &&
  4162. (ptr->core->type == MUS_COMB_BANK));
  4163. }
  4164. mus_float_t mus_comb_bank(mus_any *combs, mus_float_t inval)
  4165. {
  4166. cmb_bank *gen = (cmb_bank *)combs;
  4167. return((gen->cmbf)(combs, inval));
  4168. }
  4169. /* ---------------- notch ---------------- */
  4170. static char *describe_notch(mus_any *ptr)
  4171. {
  4172. char *str = NULL;
  4173. dly *gen = (dly *)ptr;
  4174. char *describe_buffer;
  4175. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4176. if (gen->zdly)
  4177. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u,%u, %s]: %s",
  4178. mus_name(ptr),
  4179. gen->xscl,
  4180. gen->size,
  4181. gen->zsize,
  4182. interp_type_to_string(gen->type),
  4183. str = float_array_to_string(gen->line, gen->size, gen->zloc));
  4184. else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s scaler: %.3f, line[%u, %s]: %s",
  4185. mus_name(ptr),
  4186. gen->xscl,
  4187. gen->size,
  4188. interp_type_to_string(gen->type),
  4189. str = float_array_to_string(gen->line, gen->size, gen->loc));
  4190. if (str) free(str);
  4191. return(describe_buffer);
  4192. }
  4193. static mus_any_class NOTCH_CLASS = {
  4194. MUS_NOTCH,
  4195. (char *)S_notch,
  4196. &free_delay,
  4197. &describe_notch,
  4198. &delay_equalp,
  4199. &delay_data,
  4200. &delay_set_data,
  4201. &delay_length,
  4202. &delay_set_length,
  4203. 0, 0, 0, 0, /* freq phase */
  4204. &delay_scaler,
  4205. &delay_set_scaler,
  4206. 0, 0,
  4207. &mus_notch,
  4208. MUS_DELAY_LINE,
  4209. NULL,
  4210. &delay_interp_type,
  4211. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4212. 0, 0, 0, 0,
  4213. &delay_loc,
  4214. 0, 0,
  4215. 0, 0, 0, 0,
  4216. &delay_reset,
  4217. 0, &dly_copy
  4218. };
  4219. mus_float_t mus_notch(mus_any *ptr, mus_float_t input, mus_float_t pm)
  4220. {
  4221. dly *gen = (dly *)ptr;
  4222. return((input * gen->xscl) + mus_delay(ptr, input, pm));
  4223. }
  4224. mus_float_t mus_notch_unmodulated(mus_any *ptr, mus_float_t input)
  4225. {
  4226. return((input * ((dly *)ptr)->xscl) + mus_delay_unmodulated(ptr, input));
  4227. }
  4228. #if 0
  4229. static mus_float_t mus_notch_unmodulated_noz(mus_any *ptr, mus_float_t input)
  4230. {
  4231. dly *gen = (dly *)ptr;
  4232. mus_float_t result;
  4233. result = gen->line[gen->loc] + (input * gen->xscl);
  4234. gen->line[gen->loc] = input;
  4235. gen->loc++;
  4236. if (gen->loc >= gen->size)
  4237. gen->loc = 0;
  4238. return(result);
  4239. }
  4240. #endif
  4241. bool mus_is_notch(mus_any *ptr)
  4242. {
  4243. return((ptr) &&
  4244. (ptr->core->type == MUS_NOTCH));
  4245. }
  4246. mus_any *mus_make_notch(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type)
  4247. {
  4248. dly *gen;
  4249. gen = (dly *)mus_make_delay(size, line, line_size, type);
  4250. if (gen)
  4251. {
  4252. gen->core = &NOTCH_CLASS;
  4253. gen->xscl = scaler;
  4254. return((mus_any *)gen);
  4255. }
  4256. return(NULL);
  4257. }
  4258. mus_float_t mus_all_pass(mus_any *ptr, mus_float_t input, mus_float_t pm)
  4259. {
  4260. mus_float_t din;
  4261. dly *gen = (dly *)ptr;
  4262. if (gen->zdly)
  4263. din = input + (gen->yscl * mus_tap(ptr, pm));
  4264. else din = input + (gen->yscl * gen->line[gen->loc]);
  4265. return(mus_delay(ptr, din, pm) + (gen->xscl * din));
  4266. }
  4267. mus_float_t mus_all_pass_unmodulated(mus_any *ptr, mus_float_t input)
  4268. {
  4269. mus_float_t din;
  4270. dly *gen = (dly *)ptr;
  4271. if (gen->zdly)
  4272. din = input + (gen->yscl * gen->line[gen->zloc]);
  4273. else din = input + (gen->yscl * gen->line[gen->loc]);
  4274. return(mus_delay_unmodulated(ptr, din) + (gen->xscl * din));
  4275. }
  4276. mus_float_t mus_all_pass_unmodulated_noz(mus_any *ptr, mus_float_t input)
  4277. {
  4278. mus_float_t result, din;
  4279. dly *gen = (dly *)ptr;
  4280. unsigned int loc;
  4281. loc = gen->loc++;
  4282. din = input + (gen->yscl * gen->line[loc]);
  4283. result = gen->line[loc] + (gen->xscl * din);
  4284. gen->line[loc] = din;
  4285. if (gen->loc >= gen->size)
  4286. gen->loc = 0;
  4287. return(result);
  4288. }
  4289. bool mus_is_all_pass(mus_any *ptr)
  4290. {
  4291. return((ptr) &&
  4292. (ptr->core->type == MUS_ALL_PASS));
  4293. }
  4294. static char *describe_all_pass(mus_any *ptr)
  4295. {
  4296. char *str = NULL;
  4297. dly *gen = (dly *)ptr;
  4298. char *describe_buffer;
  4299. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4300. if (gen->zdly)
  4301. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s feedback: %.3f, feedforward: %.3f, line[%u,%u, %s]:%s",
  4302. mus_name(ptr),
  4303. gen->yscl,
  4304. gen->xscl,
  4305. gen->size,
  4306. gen->zsize,
  4307. interp_type_to_string(gen->type),
  4308. str = float_array_to_string(gen->line, gen->size, gen->zloc));
  4309. else snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s feedback: %.3f, feedforward: %.3f, line[%u, %s]:%s",
  4310. mus_name(ptr),
  4311. gen->yscl,
  4312. gen->xscl,
  4313. gen->size,
  4314. interp_type_to_string(gen->type),
  4315. str = float_array_to_string(gen->line, gen->size, gen->loc));
  4316. if (str) free(str);
  4317. return(describe_buffer);
  4318. }
  4319. static mus_any_class ALL_PASS_CLASS = {
  4320. MUS_ALL_PASS,
  4321. (char *)S_all_pass,
  4322. &free_delay,
  4323. &describe_all_pass,
  4324. &delay_equalp,
  4325. &delay_data,
  4326. &delay_set_data,
  4327. &delay_length,
  4328. &delay_set_length,
  4329. 0, 0, 0, 0, /* freq phase */
  4330. &delay_scaler,
  4331. &delay_set_scaler,
  4332. &delay_fb,
  4333. &delay_set_fb,
  4334. &mus_all_pass,
  4335. MUS_DELAY_LINE,
  4336. NULL,
  4337. &delay_interp_type,
  4338. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4339. 0, 0, 0, 0,
  4340. &delay_loc,
  4341. 0, 0,
  4342. 0, 0, 0, 0,
  4343. &delay_reset,
  4344. 0, &dly_copy
  4345. };
  4346. mus_any *mus_make_all_pass(mus_float_t backward, mus_float_t forward, int size, mus_float_t *line, int line_size, mus_interp_t type)
  4347. {
  4348. dly *gen;
  4349. gen = (dly *)mus_make_delay(size, line, line_size, type);
  4350. if (gen)
  4351. {
  4352. gen->core = &ALL_PASS_CLASS;
  4353. gen->xscl = forward;
  4354. gen->yscl = backward;
  4355. return((mus_any *)gen);
  4356. }
  4357. return(NULL);
  4358. }
  4359. /* ---------------- all_pass-bank ---------------- */
  4360. typedef struct {
  4361. mus_any_class *core;
  4362. int size;
  4363. mus_any **gens;
  4364. mus_float_t (*apf)(mus_any *ptr, mus_float_t input);
  4365. } allp_bank;
  4366. static void free_all_pass_bank(mus_any *ptr)
  4367. {
  4368. allp_bank *f = (allp_bank *)ptr;
  4369. if (f->gens) {free(f->gens); f->gens = NULL;}
  4370. free(ptr);
  4371. }
  4372. static mus_any *allp_bank_copy(mus_any *ptr)
  4373. {
  4374. allp_bank *g, *p;
  4375. int i;
  4376. p = (allp_bank *)ptr;
  4377. g = (allp_bank *)malloc(sizeof(allp_bank));
  4378. memcpy((void *)g, (void *)ptr, sizeof(allp_bank));
  4379. g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *));
  4380. for (i = 0; i < p->size; i++)
  4381. g->gens[i] = mus_copy(p->gens[i]);
  4382. return((mus_any *)g);
  4383. }
  4384. static mus_float_t run_all_pass_bank(mus_any *ptr, mus_float_t input, mus_float_t unused)
  4385. {
  4386. return(mus_all_pass_bank(ptr, input));
  4387. }
  4388. static mus_long_t all_pass_bank_length(mus_any *ptr)
  4389. {
  4390. return(((allp_bank *)ptr)->size);
  4391. }
  4392. static void all_pass_bank_reset(mus_any *ptr)
  4393. {
  4394. allp_bank *f = (allp_bank *)ptr;
  4395. int i;
  4396. for (i = 0; i < f->size; i++)
  4397. mus_reset(f->gens[i]);
  4398. }
  4399. static bool all_pass_bank_equalp(mus_any *p1, mus_any *p2)
  4400. {
  4401. allp_bank *f1 = (allp_bank *)p1;
  4402. allp_bank *f2 = (allp_bank *)p2;
  4403. int i, size;
  4404. if (f1 == f2) return(true);
  4405. if (f1->size != f2->size) return(false);
  4406. size = f1->size;
  4407. for (i = 0; i < size; i++)
  4408. if (!delay_equalp(f1->gens[i], f2->gens[i]))
  4409. return(false);
  4410. return(true);
  4411. }
  4412. static char *describe_all_pass_bank(mus_any *ptr)
  4413. {
  4414. allp_bank *gen = (allp_bank *)ptr;
  4415. char *describe_buffer;
  4416. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4417. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d",
  4418. mus_name(ptr),
  4419. gen->size);
  4420. return(describe_buffer);
  4421. }
  4422. static mus_any_class ALL_PASS_BANK_CLASS = {
  4423. MUS_ALL_PASS_BANK,
  4424. (char *)S_all_pass_bank,
  4425. &free_all_pass_bank,
  4426. &describe_all_pass_bank,
  4427. &all_pass_bank_equalp,
  4428. 0, 0,
  4429. &all_pass_bank_length, 0,
  4430. 0, 0,
  4431. 0, 0,
  4432. 0, 0,
  4433. 0, 0,
  4434. &run_all_pass_bank,
  4435. MUS_NOT_SPECIAL,
  4436. NULL, 0,
  4437. 0, 0, 0, 0,
  4438. 0, 0,
  4439. 0, 0, 0, 0,
  4440. 0, 0, 0, 0, 0, 0, 0,
  4441. 0, 0, 0, 0,
  4442. &all_pass_bank_reset,
  4443. 0, &allp_bank_copy
  4444. };
  4445. static mus_float_t all_pass_bank_3(mus_any *all_passes, mus_float_t inval)
  4446. {
  4447. allp_bank *c = (allp_bank *)all_passes;
  4448. mus_any **gs;
  4449. gs = c->gens;
  4450. return(mus_all_pass_unmodulated_noz(gs[2], mus_all_pass_unmodulated_noz(gs[1], mus_all_pass_unmodulated_noz(gs[0], inval))));
  4451. }
  4452. static mus_float_t all_pass_bank_4(mus_any *all_passes, mus_float_t inval)
  4453. {
  4454. allp_bank *c = (allp_bank *)all_passes;
  4455. mus_any **gs;
  4456. gs = c->gens;
  4457. return(mus_all_pass_unmodulated_noz(gs[3], mus_all_pass_unmodulated_noz(gs[2], mus_all_pass_unmodulated_noz(gs[1], mus_all_pass_unmodulated_noz(gs[0], inval)))));
  4458. }
  4459. static mus_float_t all_pass_bank_any(mus_any *all_passs, mus_float_t inval)
  4460. {
  4461. int i;
  4462. mus_float_t sum = inval;
  4463. allp_bank *c = (allp_bank *)all_passs;
  4464. for (i = 0; i < c->size; i++)
  4465. sum = mus_all_pass_unmodulated_noz(c->gens[i], sum);
  4466. return(sum);
  4467. }
  4468. mus_any *mus_make_all_pass_bank(int size, mus_any **all_passs)
  4469. {
  4470. allp_bank *gen;
  4471. int i;
  4472. gen = (allp_bank *)malloc(sizeof(allp_bank));
  4473. gen->core = &ALL_PASS_BANK_CLASS;
  4474. gen->size = size;
  4475. gen->gens = (mus_any **)malloc(size * sizeof(mus_any *));
  4476. for (i = 0; i < size; i++)
  4477. gen->gens[i] = all_passs[i];
  4478. if (size == 3)
  4479. gen->apf = all_pass_bank_3;
  4480. else
  4481. {
  4482. if (size == 4)
  4483. gen->apf = all_pass_bank_4;
  4484. else gen->apf = all_pass_bank_any;
  4485. }
  4486. return((mus_any *)gen);
  4487. }
  4488. bool mus_is_all_pass_bank(mus_any *ptr)
  4489. {
  4490. return((ptr) &&
  4491. (ptr->core->type == MUS_ALL_PASS_BANK));
  4492. }
  4493. mus_float_t mus_all_pass_bank(mus_any *all_passes, mus_float_t inval)
  4494. {
  4495. allp_bank *gen = (allp_bank *)all_passes;
  4496. return((gen->apf)(all_passes, inval));
  4497. }
  4498. /* ---------------- moving-average ---------------- */
  4499. bool mus_is_moving_average(mus_any *ptr)
  4500. {
  4501. return((ptr) &&
  4502. (ptr->core->type == MUS_MOVING_AVERAGE));
  4503. }
  4504. mus_float_t mus_moving_average(mus_any *ptr, mus_float_t input)
  4505. {
  4506. dly *gen = (dly *)ptr;
  4507. mus_float_t output;
  4508. output = mus_delay_unmodulated_noz(ptr, input);
  4509. gen->xscl += (input - output);
  4510. return(gen->xscl * gen->yscl); /* xscl=sum, yscl=1/n */
  4511. }
  4512. static mus_float_t run_mus_moving_average(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_average(ptr, input));}
  4513. static void moving_average_reset(mus_any *ptr)
  4514. {
  4515. dly *gen = (dly *)ptr;
  4516. delay_reset(ptr);
  4517. gen->xscl = 0.0;
  4518. }
  4519. static char *describe_moving_average(mus_any *ptr)
  4520. {
  4521. char *str = NULL;
  4522. dly *gen = (dly *)ptr;
  4523. char *describe_buffer;
  4524. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4525. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %.3f, line[%u]:%s",
  4526. mus_name(ptr),
  4527. gen->xscl * gen->yscl,
  4528. gen->size,
  4529. str = float_array_to_string(gen->line, gen->size, gen->loc));
  4530. if (str) free(str);
  4531. return(describe_buffer);
  4532. }
  4533. static mus_any_class MOVING_AVERAGE_CLASS = {
  4534. MUS_MOVING_AVERAGE,
  4535. (char *)S_moving_average,
  4536. &free_delay,
  4537. &describe_moving_average,
  4538. &delay_equalp,
  4539. &delay_data,
  4540. &delay_set_data,
  4541. &delay_length,
  4542. &delay_set_length,
  4543. 0, 0, 0, 0, /* freq phase */
  4544. &delay_scaler,
  4545. &delay_set_scaler,
  4546. &delay_fb,
  4547. &delay_set_fb,
  4548. &run_mus_moving_average,
  4549. MUS_DELAY_LINE,
  4550. NULL, 0,
  4551. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4552. 0, 0, 0, 0,
  4553. &delay_loc,
  4554. 0, 0,
  4555. 0, 0, 0, 0,
  4556. &moving_average_reset,
  4557. 0, &dly_copy
  4558. };
  4559. mus_any *mus_make_moving_average(int size, mus_float_t *line)
  4560. {
  4561. dly *gen;
  4562. gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE);
  4563. if (gen)
  4564. {
  4565. int i;
  4566. gen->core = &MOVING_AVERAGE_CLASS;
  4567. gen->xscl = 0.0;
  4568. for (i = 0; i < size; i++)
  4569. gen->xscl += gen->line[i];
  4570. gen->yscl = 1.0 / (mus_float_t)size;
  4571. return((mus_any *)gen);
  4572. }
  4573. return(NULL);
  4574. }
  4575. mus_any *mus_make_moving_average_with_initial_sum(int size, mus_float_t *line, mus_float_t sum)
  4576. {
  4577. dly *gen;
  4578. gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE);
  4579. if (gen)
  4580. {
  4581. gen->core = &MOVING_AVERAGE_CLASS;
  4582. gen->xscl = sum;
  4583. gen->yscl = 1.0 / (mus_float_t)size;
  4584. return((mus_any *)gen);
  4585. }
  4586. return(NULL);
  4587. }
  4588. /* -------- moving-max -------- */
  4589. bool mus_is_moving_max(mus_any *ptr)
  4590. {
  4591. return((ptr) &&
  4592. (ptr->core->type == MUS_MOVING_MAX));
  4593. }
  4594. mus_float_t mus_moving_max(mus_any *ptr, mus_float_t input)
  4595. {
  4596. dly *gen = (dly *)ptr;
  4597. mus_float_t output, abs_input;
  4598. abs_input = fabs(input);
  4599. output = mus_delay_unmodulated_noz(ptr, abs_input);
  4600. if (abs_input >= gen->xscl)
  4601. gen->xscl = abs_input;
  4602. else
  4603. {
  4604. if (output >= gen->xscl)
  4605. {
  4606. unsigned int i;
  4607. for (i = 0; i < gen->size; i++)
  4608. if (gen->line[i] > abs_input)
  4609. abs_input = gen->line[i];
  4610. gen->xscl = abs_input;
  4611. }
  4612. }
  4613. return(gen->xscl);
  4614. }
  4615. static mus_float_t run_mus_moving_max(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_max(ptr, input));}
  4616. static void moving_max_reset(mus_any *ptr)
  4617. {
  4618. dly *gen = (dly *)ptr;
  4619. delay_reset(ptr);
  4620. gen->xscl = 0.0;
  4621. }
  4622. static char *describe_moving_max(mus_any *ptr)
  4623. {
  4624. char *str = NULL;
  4625. dly *gen = (dly *)ptr;
  4626. char *describe_buffer;
  4627. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4628. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %.3f, line[%u]:%s",
  4629. mus_name(ptr),
  4630. gen->xscl,
  4631. gen->size,
  4632. str = float_array_to_string(gen->line, gen->size, gen->loc));
  4633. if (str) free(str);
  4634. return(describe_buffer);
  4635. }
  4636. static mus_any_class MOVING_MAX_CLASS = {
  4637. MUS_MOVING_MAX,
  4638. (char *)S_moving_max,
  4639. &free_delay,
  4640. &describe_moving_max,
  4641. &delay_equalp,
  4642. &delay_data,
  4643. &delay_set_data,
  4644. &delay_length,
  4645. &delay_set_length,
  4646. 0, 0, 0, 0, /* freq phase */
  4647. &delay_scaler,
  4648. &delay_set_scaler,
  4649. &delay_fb,
  4650. &delay_set_fb,
  4651. &run_mus_moving_max,
  4652. MUS_DELAY_LINE,
  4653. NULL, 0,
  4654. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4655. 0, 0, 0, 0,
  4656. &delay_loc,
  4657. 0, 0,
  4658. 0, 0, 0, 0,
  4659. &moving_max_reset,
  4660. 0, &dly_copy
  4661. };
  4662. mus_any *mus_make_moving_max(int size, mus_float_t *line)
  4663. {
  4664. dly *gen;
  4665. gen = (dly *)mus_make_delay(size, line, size, MUS_INTERP_NONE);
  4666. if (gen)
  4667. {
  4668. int i;
  4669. gen->core = &MOVING_MAX_CLASS;
  4670. gen->xscl = 0.0;
  4671. for (i = 0; i < size; i++)
  4672. if (fabs(gen->line[i]) > gen->xscl)
  4673. gen->xscl = fabs(gen->line[i]);
  4674. return((mus_any *)gen);
  4675. }
  4676. return(NULL);
  4677. }
  4678. /* -------- moving-norm -------- */
  4679. bool mus_is_moving_norm(mus_any *ptr)
  4680. {
  4681. return((ptr) &&
  4682. (ptr->core->type == MUS_MOVING_NORM));
  4683. }
  4684. mus_float_t mus_moving_norm(mus_any *ptr, mus_float_t input)
  4685. {
  4686. dly *gen = (dly *)ptr;
  4687. mus_float_t output, abs_input;
  4688. abs_input = fabs(input);
  4689. if (abs_input < 0.01) abs_input = 0.01; /* 0.01 sets the max norm output (~100) -- maybe a parameter to make-norm? */
  4690. output = mus_moving_max(ptr, abs_input);
  4691. gen->y1 = output + (gen->yscl * gen->y1);
  4692. return(gen->norm / gen->y1);
  4693. }
  4694. static mus_float_t run_mus_moving_norm(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_moving_norm(ptr, input));}
  4695. static void moving_norm_reset(mus_any *ptr)
  4696. {
  4697. dly *gen = (dly *)ptr;
  4698. delay_reset(ptr);
  4699. gen->xscl = 0.0;
  4700. gen->y1 = 0.0;
  4701. }
  4702. static char *describe_moving_norm(mus_any *ptr)
  4703. {
  4704. char *str = NULL;
  4705. dly *gen = (dly *)ptr;
  4706. char *describe_buffer;
  4707. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4708. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s, max %.3f, y1 %.3f, weight %.3f, line[%u]:%s",
  4709. mus_name(ptr),
  4710. gen->xscl, gen->y1, gen->yscl,
  4711. gen->size,
  4712. str = float_array_to_string(gen->line, gen->size, gen->loc));
  4713. if (str) free(str);
  4714. return(describe_buffer);
  4715. }
  4716. static mus_any_class MOVING_NORM_CLASS = {
  4717. MUS_MOVING_NORM,
  4718. (char *)S_moving_norm,
  4719. &free_delay,
  4720. &describe_moving_norm,
  4721. &delay_equalp,
  4722. &delay_data,
  4723. &delay_set_data,
  4724. &delay_length,
  4725. &delay_set_length,
  4726. 0, 0, 0, 0, /* freq phase */
  4727. &delay_scaler,
  4728. &delay_set_scaler,
  4729. &delay_fb,
  4730. &delay_set_fb,
  4731. &run_mus_moving_norm,
  4732. MUS_DELAY_LINE,
  4733. NULL, 0,
  4734. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4735. 0, 0, 0, 0,
  4736. &delay_loc,
  4737. 0, 0,
  4738. 0, 0, 0, 0,
  4739. &moving_norm_reset,
  4740. 0, &dly_copy
  4741. };
  4742. mus_any *mus_make_moving_norm(int size, mus_float_t *line, mus_float_t norm)
  4743. {
  4744. dly *gen;
  4745. gen = (dly *)mus_make_moving_max(size, line);
  4746. if (gen)
  4747. {
  4748. gen->core = &MOVING_NORM_CLASS;
  4749. gen->yscl = (mus_float_t)size / (size + 1.0); /* one-pole -b1 = -feedback so this is a lowpass filter */
  4750. gen->norm = norm * (size + 1.0);
  4751. gen->yn1 = 1.0 / size;
  4752. gen->y1 = size + 1.0;
  4753. return((mus_any *)gen);
  4754. }
  4755. return(NULL);
  4756. }
  4757. /* ---------------------------------------- filtered-comb ---------------------------------------- */
  4758. static void filtered_comb_reset(mus_any *ptr)
  4759. {
  4760. dly *fc = (dly *)ptr;
  4761. delay_reset(ptr);
  4762. mus_reset(fc->filt);
  4763. }
  4764. static bool filtered_comb_equalp(mus_any *p1, mus_any *p2)
  4765. {
  4766. return((delay_equalp(p1, p2)) &&
  4767. (mus_equalp(((dly *)p1)->filt,
  4768. ((dly *)p2)->filt)));
  4769. }
  4770. static char *describe_filtered_comb(mus_any *ptr)
  4771. {
  4772. char *comb_str, *filter_str, *res;
  4773. int len;
  4774. comb_str = describe_comb(ptr);
  4775. filter_str = mus_describe(((dly *)ptr)->filt);
  4776. len = strlen(comb_str) + strlen(filter_str) + 64;
  4777. res = (char *)malloc(len * sizeof(char));
  4778. snprintf(res, len, "%s, filter: [%s]", comb_str, filter_str);
  4779. if (comb_str) free(comb_str);
  4780. if (filter_str) free(filter_str);
  4781. return(res);
  4782. }
  4783. bool mus_is_filtered_comb(mus_any *ptr)
  4784. {
  4785. return((ptr) &&
  4786. (ptr->core->type == MUS_FILTERED_COMB));
  4787. }
  4788. mus_float_t mus_filtered_comb(mus_any *ptr, mus_float_t input, mus_float_t pm)
  4789. {
  4790. dly *fc = (dly *)ptr;
  4791. if (fc->zdly)
  4792. return(mus_delay(ptr,
  4793. input + (fc->yscl *
  4794. fc->runf(fc->filt,
  4795. mus_tap(ptr, pm),
  4796. 0.0)),
  4797. pm));
  4798. return(mus_delay_unmodulated(ptr,
  4799. input + (fc->yscl *
  4800. fc->runf(fc->filt, fc->line[fc->loc], 0.0))));
  4801. }
  4802. mus_float_t mus_filtered_comb_unmodulated(mus_any *ptr, mus_float_t input)
  4803. {
  4804. dly *fc = (dly *)ptr;
  4805. return(mus_delay_unmodulated(ptr,
  4806. input + (fc->yscl *
  4807. fc->runf(fc->filt, fc->line[fc->loc], 0.0))));
  4808. }
  4809. static mus_any_class FILTERED_COMB_CLASS = {
  4810. MUS_FILTERED_COMB,
  4811. (char *)S_filtered_comb,
  4812. &free_delay,
  4813. &describe_filtered_comb,
  4814. &filtered_comb_equalp,
  4815. &delay_data,
  4816. &delay_set_data,
  4817. &delay_length,
  4818. &delay_set_length,
  4819. 0, 0, 0, 0, /* freq phase */
  4820. &delay_scaler,
  4821. &delay_set_scaler,
  4822. &delay_fb,
  4823. &delay_set_fb,
  4824. &mus_filtered_comb,
  4825. MUS_DELAY_LINE,
  4826. NULL,
  4827. &delay_interp_type,
  4828. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4829. 0, 0, 0, 0,
  4830. &delay_loc,
  4831. 0, 0,
  4832. 0, 0, 0, 0,
  4833. &filtered_comb_reset,
  4834. 0, &dly_copy
  4835. };
  4836. mus_any *mus_make_filtered_comb(mus_float_t scaler, int size, mus_float_t *line, int line_size, mus_interp_t type, mus_any *filt)
  4837. {
  4838. dly *fc;
  4839. fc = (dly *)mus_make_comb(scaler, size, line, line_size, type);
  4840. if (fc)
  4841. {
  4842. fc->core = &FILTERED_COMB_CLASS;
  4843. if (filt)
  4844. fc->filt = filt;
  4845. else
  4846. {
  4847. fc->filt = mus_make_one_zero(1.0, 0.0);
  4848. fc->filt_allocated = true;
  4849. }
  4850. fc->runf = mus_run_function(fc->filt);
  4851. return((mus_any *)fc);
  4852. }
  4853. else return(NULL);
  4854. }
  4855. /* ---------------- filtered-comb-bank ---------------- */
  4856. typedef struct {
  4857. mus_any_class *core;
  4858. int size;
  4859. mus_any **gens;
  4860. mus_float_t (*cmbf)(mus_any *ptr, mus_float_t input);
  4861. } fltcmb_bank;
  4862. static void free_filtered_comb_bank(mus_any *ptr)
  4863. {
  4864. fltcmb_bank *f = (fltcmb_bank *)ptr;
  4865. if (f->gens) {free(f->gens); f->gens = NULL;}
  4866. free(ptr);
  4867. }
  4868. static mus_any *fltcmb_bank_copy(mus_any *ptr)
  4869. {
  4870. fltcmb_bank *g, *p;
  4871. int i;
  4872. p = (fltcmb_bank *)ptr;
  4873. g = (fltcmb_bank *)malloc(sizeof(fltcmb_bank));
  4874. memcpy((void *)g, (void *)ptr, sizeof(fltcmb_bank));
  4875. g->gens = (mus_any **)malloc(p->size * sizeof(mus_any *));
  4876. for (i = 0; i < p->size; i++)
  4877. g->gens[i] = mus_copy(p->gens[i]);
  4878. return((mus_any *)g);
  4879. }
  4880. static mus_float_t run_filtered_comb_bank(mus_any *ptr, mus_float_t input, mus_float_t unused)
  4881. {
  4882. return(mus_filtered_comb_bank(ptr, input));
  4883. }
  4884. static mus_long_t filtered_comb_bank_length(mus_any *ptr)
  4885. {
  4886. return(((fltcmb_bank *)ptr)->size);
  4887. }
  4888. static void filtered_comb_bank_reset(mus_any *ptr)
  4889. {
  4890. fltcmb_bank *f = (fltcmb_bank *)ptr;
  4891. int i;
  4892. for (i = 0; i < f->size; i++)
  4893. mus_reset(f->gens[i]);
  4894. }
  4895. static bool filtered_comb_bank_equalp(mus_any *p1, mus_any *p2)
  4896. {
  4897. fltcmb_bank *f1 = (fltcmb_bank *)p1;
  4898. fltcmb_bank *f2 = (fltcmb_bank *)p2;
  4899. int i, size;
  4900. if (f1 == f2) return(true);
  4901. if (f1->size != f2->size) return(false);
  4902. size = f1->size;
  4903. for (i = 0; i < size; i++)
  4904. if (!filtered_comb_equalp(f1->gens[i], f2->gens[i]))
  4905. return(false);
  4906. return(true);
  4907. }
  4908. static char *describe_filtered_comb_bank(mus_any *ptr)
  4909. {
  4910. fltcmb_bank *gen = (fltcmb_bank *)ptr;
  4911. char *describe_buffer;
  4912. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  4913. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d",
  4914. mus_name(ptr),
  4915. gen->size);
  4916. return(describe_buffer);
  4917. }
  4918. static mus_any_class FILTERED_COMB_BANK_CLASS = {
  4919. MUS_FILTERED_COMB_BANK,
  4920. (char *)S_filtered_comb_bank,
  4921. &free_filtered_comb_bank,
  4922. &describe_filtered_comb_bank,
  4923. &filtered_comb_bank_equalp,
  4924. 0, 0,
  4925. &filtered_comb_bank_length, 0,
  4926. 0, 0,
  4927. 0, 0,
  4928. 0, 0,
  4929. 0, 0,
  4930. &run_filtered_comb_bank,
  4931. MUS_NOT_SPECIAL,
  4932. NULL, 0,
  4933. 0, 0, 0, 0,
  4934. 0, 0,
  4935. 0, 0, 0, 0,
  4936. 0, 0, 0, 0, 0, 0, 0,
  4937. 0, 0, 0, 0,
  4938. &filtered_comb_bank_reset,
  4939. 0, &fltcmb_bank_copy
  4940. };
  4941. static mus_float_t filtered_comb_one_zero(mus_any *ptr, mus_float_t input)
  4942. {
  4943. dly *gen = (dly *)ptr;
  4944. mus_float_t result;
  4945. result = gen->line[gen->loc];
  4946. gen->line[gen->loc] = input + mus_one_zero(gen->filt, result); /* gen->yscl folded into one_zero coeffs via smp_scl */
  4947. gen->loc++;
  4948. if (gen->loc >= gen->size)
  4949. gen->loc = 0;
  4950. return(result);
  4951. }
  4952. static mus_float_t filtered_comb_bank_8(mus_any *combs, mus_float_t inval)
  4953. {
  4954. fltcmb_bank *c = (fltcmb_bank *)combs;
  4955. mus_any **gs;
  4956. gs = c->gens;
  4957. return(filtered_comb_one_zero(gs[0], inval) +
  4958. filtered_comb_one_zero(gs[1], inval) +
  4959. filtered_comb_one_zero(gs[2], inval) +
  4960. filtered_comb_one_zero(gs[3], inval) +
  4961. filtered_comb_one_zero(gs[4], inval) +
  4962. filtered_comb_one_zero(gs[5], inval) +
  4963. filtered_comb_one_zero(gs[6], inval) +
  4964. filtered_comb_one_zero(gs[7], inval));
  4965. }
  4966. static mus_float_t filtered_comb_bank_any(mus_any *filtered_combs, mus_float_t inval)
  4967. {
  4968. int i;
  4969. mus_float_t sum = 0.0;
  4970. fltcmb_bank *c = (fltcmb_bank *)filtered_combs;
  4971. for (i = 0; i < c->size; i++)
  4972. sum += mus_filtered_comb_unmodulated(c->gens[i], inval);
  4973. return(sum);
  4974. }
  4975. static void smp_scl(mus_any *ptr, mus_float_t scl);
  4976. mus_any *mus_make_filtered_comb_bank(int size, mus_any **filtered_combs)
  4977. {
  4978. fltcmb_bank *gen;
  4979. int i;
  4980. bool zdly = false, oz = true;
  4981. gen = (fltcmb_bank *)malloc(sizeof(fltcmb_bank));
  4982. gen->core = &FILTERED_COMB_BANK_CLASS;
  4983. gen->size = size;
  4984. gen->gens = (mus_any **)malloc(size * sizeof(mus_any *));
  4985. for (i = 0; i < size; i++)
  4986. {
  4987. gen->gens[i] = filtered_combs[i];
  4988. zdly = (zdly) || (((dly *)(filtered_combs[i]))->zdly);
  4989. oz = (oz) && (mus_is_one_zero(((dly *)(filtered_combs[i]))->filt));
  4990. }
  4991. if ((size == 8) &&
  4992. (oz) &&
  4993. (!zdly))
  4994. {
  4995. gen->cmbf = filtered_comb_bank_8;
  4996. for (i = 0; i < 8; i++)
  4997. {
  4998. dly *d;
  4999. d = (dly *)gen->gens[i];
  5000. smp_scl(d->filt, d->yscl);
  5001. }
  5002. }
  5003. else gen->cmbf = filtered_comb_bank_any;
  5004. return((mus_any *)gen);
  5005. }
  5006. bool mus_is_filtered_comb_bank(mus_any *ptr)
  5007. {
  5008. return((ptr) &&
  5009. (ptr->core->type == MUS_FILTERED_COMB_BANK));
  5010. }
  5011. mus_float_t mus_filtered_comb_bank(mus_any *filtered_combs, mus_float_t inval)
  5012. {
  5013. fltcmb_bank *gen = (fltcmb_bank *)filtered_combs;
  5014. return((gen->cmbf)(filtered_combs, inval));
  5015. }
  5016. mus_any *mus_bank_generator(mus_any *g, int i)
  5017. {
  5018. if (mus_is_comb_bank(g))
  5019. return(((cmb_bank *)g)->gens[i]);
  5020. if (mus_is_all_pass_bank(g))
  5021. return(((allp_bank *)g)->gens[i]);
  5022. if (mus_is_filtered_comb_bank(g))
  5023. return(((fltcmb_bank *)g)->gens[i]);
  5024. return(NULL);
  5025. }
  5026. /* ---------------- sawtooth et al ---------------- */
  5027. typedef struct {
  5028. mus_any_class *core;
  5029. mus_float_t current_value;
  5030. mus_float_t freq, phase, base, width;
  5031. } sw;
  5032. static void free_sw(mus_any *ptr) {free(ptr);}
  5033. static mus_any *sw_copy(mus_any *ptr)
  5034. {
  5035. sw *g;
  5036. g = (sw *)malloc(sizeof(sw));
  5037. memcpy((void *)g, (void *)ptr, sizeof(sw));
  5038. return((mus_any *)g);
  5039. }
  5040. mus_float_t mus_sawtooth_wave(mus_any *ptr, mus_float_t fm)
  5041. {
  5042. sw *gen = (sw *)ptr;
  5043. mus_float_t result;
  5044. result = gen->current_value;
  5045. gen->phase += (gen->freq + fm);
  5046. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5047. {
  5048. gen->phase = fmod(gen->phase, TWO_PI);
  5049. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5050. }
  5051. gen->current_value = gen->base * (gen->phase - M_PI);
  5052. return(result);
  5053. }
  5054. static mus_float_t run_sawtooth_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_sawtooth_wave(ptr, fm));}
  5055. bool mus_is_sawtooth_wave(mus_any *ptr)
  5056. {
  5057. return((ptr) &&
  5058. (ptr->core->type == MUS_SAWTOOTH_WAVE));
  5059. }
  5060. static mus_float_t sw_freq(mus_any *ptr) {return(mus_radians_to_hz(((sw *)ptr)->freq));}
  5061. static mus_float_t sw_set_freq(mus_any *ptr, mus_float_t val) {((sw *)ptr)->freq = mus_hz_to_radians(val); return(val);}
  5062. static mus_float_t sw_increment(mus_any *ptr) {return(((sw *)ptr)->freq);}
  5063. static mus_float_t sw_set_increment(mus_any *ptr, mus_float_t val) {((sw *)ptr)->freq = val; return(val);}
  5064. static mus_float_t sw_phase(mus_any *ptr) {return(fmod(((sw *)ptr)->phase, TWO_PI));}
  5065. static mus_float_t sw_set_phase(mus_any *ptr, mus_float_t val) {((sw *)ptr)->phase = val; return(val);}
  5066. static mus_float_t sw_width(mus_any *ptr) {return((((sw *)ptr)->width) / ( 2 * M_PI));}
  5067. static mus_float_t sw_set_width(mus_any *ptr, mus_float_t val) {((sw *)ptr)->width = (2 * M_PI * val); return(val);}
  5068. static mus_float_t sawtooth_scaler(mus_any *ptr) {return(((sw *)ptr)->base * M_PI);}
  5069. static mus_float_t sawtooth_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val / M_PI; return(val);}
  5070. static bool sw_equalp(mus_any *p1, mus_any *p2)
  5071. {
  5072. sw *s1, *s2;
  5073. s1 = (sw *)p1;
  5074. s2 = (sw *)p2;
  5075. return((p1 == p2) ||
  5076. ((s1) && (s2) &&
  5077. (s1->core->type == s2->core->type) &&
  5078. (s1->freq == s2->freq) &&
  5079. (s1->phase == s2->phase) &&
  5080. (s1->base == s2->base) &&
  5081. (s1->current_value == s2->current_value)));
  5082. }
  5083. static char *describe_sw(mus_any *ptr)
  5084. {
  5085. char *describe_buffer;
  5086. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  5087. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f",
  5088. mus_name(ptr),
  5089. mus_frequency(ptr),
  5090. mus_phase(ptr),
  5091. mus_scaler(ptr));
  5092. return(describe_buffer);
  5093. }
  5094. static void sawtooth_reset(mus_any *ptr)
  5095. {
  5096. sw *gen = (sw *)ptr;
  5097. gen->phase = M_PI;
  5098. gen->current_value = 0.0;
  5099. }
  5100. static mus_any_class SAWTOOTH_WAVE_CLASS = {
  5101. MUS_SAWTOOTH_WAVE,
  5102. (char *)S_sawtooth_wave,
  5103. &free_sw,
  5104. &describe_sw,
  5105. &sw_equalp,
  5106. 0, 0, 0, 0,
  5107. &sw_freq,
  5108. &sw_set_freq,
  5109. &sw_phase,
  5110. &sw_set_phase,
  5111. &sawtooth_scaler,
  5112. &sawtooth_set_scaler,
  5113. &sw_increment,
  5114. &sw_set_increment,
  5115. &run_sawtooth_wave,
  5116. MUS_NOT_SPECIAL,
  5117. NULL, 0,
  5118. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  5119. 0, 0, 0, 0, 0, 0, 0,
  5120. 0, 0, 0, 0,
  5121. &sawtooth_reset,
  5122. 0, &sw_copy
  5123. };
  5124. mus_any *mus_make_sawtooth_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase) /* M_PI as initial phase, normally */
  5125. {
  5126. sw *gen;
  5127. gen = (sw *)malloc(sizeof(sw));
  5128. gen->core = &SAWTOOTH_WAVE_CLASS;
  5129. gen->freq = mus_hz_to_radians(freq);
  5130. gen->base = (amp / M_PI);
  5131. gen->phase = phase;
  5132. gen->current_value = gen->base * (gen->phase - M_PI);
  5133. return((mus_any *)gen);
  5134. }
  5135. mus_float_t mus_square_wave(mus_any *ptr, mus_float_t fm)
  5136. {
  5137. sw *gen = (sw *)ptr;
  5138. mus_float_t result;
  5139. result = gen->current_value;
  5140. gen->phase += (gen->freq + fm);
  5141. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5142. {
  5143. gen->phase = fmod(gen->phase, TWO_PI);
  5144. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5145. }
  5146. if (gen->phase < gen->width)
  5147. gen->current_value = gen->base;
  5148. else gen->current_value = 0.0;
  5149. return(result);
  5150. }
  5151. bool mus_is_square_wave(mus_any *ptr)
  5152. {
  5153. return((ptr) &&
  5154. (ptr->core->type == MUS_SQUARE_WAVE));
  5155. }
  5156. static mus_float_t run_square_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_square_wave(ptr, fm));}
  5157. static mus_float_t square_wave_scaler(mus_any *ptr) {return(((sw *)ptr)->base);}
  5158. static mus_float_t square_wave_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val; return(val);}
  5159. static void square_wave_reset(mus_any *ptr)
  5160. {
  5161. sw *gen = (sw *)ptr;
  5162. gen->phase = 0.0;
  5163. gen->current_value = gen->base;
  5164. }
  5165. static mus_any_class SQUARE_WAVE_CLASS = {
  5166. MUS_SQUARE_WAVE,
  5167. (char *)S_square_wave,
  5168. &free_sw,
  5169. &describe_sw,
  5170. &sw_equalp,
  5171. 0, 0, 0, 0,
  5172. &sw_freq,
  5173. &sw_set_freq,
  5174. &sw_phase,
  5175. &sw_set_phase,
  5176. &square_wave_scaler,
  5177. &square_wave_set_scaler,
  5178. &sw_increment,
  5179. &sw_set_increment,
  5180. &run_square_wave,
  5181. MUS_NOT_SPECIAL,
  5182. NULL, 0,
  5183. 0, 0,
  5184. &sw_width, &sw_set_width,
  5185. 0, 0,
  5186. 0, 0, 0, 0,
  5187. 0, 0, 0, 0, 0, 0, 0,
  5188. 0, 0, 0, 0,
  5189. &square_wave_reset,
  5190. 0, &sw_copy
  5191. };
  5192. mus_any *mus_make_square_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase)
  5193. {
  5194. sw *gen;
  5195. gen = (sw *)malloc(sizeof(sw));
  5196. gen->core = &SQUARE_WAVE_CLASS;
  5197. gen->freq = mus_hz_to_radians(freq);
  5198. gen->base = amp;
  5199. gen->phase = phase;
  5200. gen->width = M_PI;
  5201. if (gen->phase < gen->width)
  5202. gen->current_value = gen->base;
  5203. else gen->current_value = 0.0;
  5204. return((mus_any *)gen);
  5205. }
  5206. mus_float_t mus_triangle_wave(mus_any *ptr, mus_float_t fm)
  5207. {
  5208. sw *gen = (sw *)ptr;
  5209. mus_float_t result;
  5210. result = gen->current_value;
  5211. gen->phase += (gen->freq + fm);
  5212. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5213. {
  5214. gen->phase = fmod(gen->phase, TWO_PI);
  5215. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5216. }
  5217. if (gen->phase < (M_PI / 2.0))
  5218. gen->current_value = gen->base * gen->phase;
  5219. else
  5220. if (gen->phase < (M_PI * 1.5))
  5221. gen->current_value = gen->base * (M_PI - gen->phase);
  5222. else gen->current_value = gen->base * (gen->phase - TWO_PI);
  5223. return(result);
  5224. }
  5225. mus_float_t mus_triangle_wave_unmodulated(mus_any *ptr)
  5226. {
  5227. sw *gen = (sw *)ptr;
  5228. mus_float_t result;
  5229. result = gen->current_value;
  5230. gen->phase += gen->freq;
  5231. TRY_AGAIN:
  5232. if (gen->phase < (M_PI / 2.0))
  5233. gen->current_value = gen->base * gen->phase;
  5234. else
  5235. {
  5236. if (gen->phase < (M_PI * 1.5))
  5237. gen->current_value = gen->base * (M_PI - gen->phase);
  5238. else
  5239. {
  5240. if (gen->phase < TWO_PI)
  5241. gen->current_value = gen->base * (gen->phase - TWO_PI);
  5242. else
  5243. {
  5244. gen->phase -= TWO_PI;
  5245. goto TRY_AGAIN;
  5246. }
  5247. }
  5248. }
  5249. return(result);
  5250. }
  5251. bool mus_is_triangle_wave(mus_any *ptr)
  5252. {
  5253. return((ptr) &&
  5254. (ptr->core->type == MUS_TRIANGLE_WAVE));
  5255. }
  5256. static mus_float_t run_triangle_wave(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_triangle_wave(ptr, fm));}
  5257. static mus_float_t triangle_wave_scaler(mus_any *ptr) {return(((sw *)ptr)->base * M_PI_2);}
  5258. static mus_float_t triangle_wave_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = (val * 2.0 / M_PI); return(val);}
  5259. static void triangle_wave_reset(mus_any *ptr)
  5260. {
  5261. sw *gen = (sw *)ptr;
  5262. gen->phase = 0.0;
  5263. gen->current_value = 0.0;
  5264. }
  5265. static mus_any_class TRIANGLE_WAVE_CLASS = {
  5266. MUS_TRIANGLE_WAVE,
  5267. (char *)S_triangle_wave,
  5268. &free_sw,
  5269. &describe_sw,
  5270. &sw_equalp,
  5271. 0, 0, 0, 0,
  5272. &sw_freq,
  5273. &sw_set_freq,
  5274. &sw_phase,
  5275. &sw_set_phase,
  5276. &triangle_wave_scaler,
  5277. &triangle_wave_set_scaler,
  5278. &sw_increment,
  5279. &sw_set_increment,
  5280. &run_triangle_wave,
  5281. MUS_NOT_SPECIAL,
  5282. NULL, 0,
  5283. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  5284. 0, 0, 0, 0, 0, 0, 0,
  5285. 0, 0, 0, 0,
  5286. &triangle_wave_reset,
  5287. 0, &sw_copy
  5288. };
  5289. mus_any *mus_make_triangle_wave(mus_float_t freq, mus_float_t amp, mus_float_t phase)
  5290. {
  5291. sw *gen;
  5292. gen = (sw *)malloc(sizeof(sw));
  5293. gen->core = &TRIANGLE_WAVE_CLASS;
  5294. if (freq < 0.0)
  5295. {
  5296. freq = -freq;
  5297. phase += M_PI;
  5298. if (phase > TWO_PI) phase -= TWO_PI;
  5299. }
  5300. gen->freq = mus_hz_to_radians(freq);
  5301. gen->base = (2.0 * amp / M_PI);
  5302. gen->phase = phase;
  5303. if (gen->phase < M_PI_2)
  5304. gen->current_value = gen->base * gen->phase;
  5305. else
  5306. if (gen->phase < (M_PI * 1.5))
  5307. gen->current_value = gen->base * (M_PI - gen->phase);
  5308. else gen->current_value = gen->base * (gen->phase - TWO_PI);
  5309. return((mus_any *)gen);
  5310. }
  5311. mus_float_t mus_pulse_train(mus_any *ptr, mus_float_t fm)
  5312. {
  5313. sw *gen = (sw *)ptr;
  5314. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5315. {
  5316. gen->phase = fmod(gen->phase, TWO_PI);
  5317. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5318. gen->current_value = gen->base;
  5319. }
  5320. else gen->current_value = 0.0;
  5321. gen->phase += (gen->freq + fm);
  5322. return(gen->current_value);
  5323. }
  5324. mus_float_t mus_pulse_train_unmodulated(mus_any *ptr)
  5325. {
  5326. sw *gen = (sw *)ptr;
  5327. /* here unfortunately, we might get any phase: (pulse-train p (+ (pulse-train p) -1.0))
  5328. */
  5329. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5330. {
  5331. gen->phase = fmod(gen->phase, TWO_PI);
  5332. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5333. gen->current_value = gen->base;
  5334. }
  5335. else gen->current_value = 0.0;
  5336. gen->phase += gen->freq;
  5337. return(gen->current_value);
  5338. }
  5339. bool mus_is_pulse_train(mus_any *ptr)
  5340. {
  5341. return((ptr) &&
  5342. (ptr->core->type == MUS_PULSE_TRAIN));
  5343. }
  5344. static mus_float_t run_pulse_train(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_pulse_train(ptr, fm));}
  5345. static mus_float_t pulse_train_scaler(mus_any *ptr) {return(((sw *)ptr)->base);}
  5346. static mus_float_t pulse_train_set_scaler(mus_any *ptr, mus_float_t val) {((sw *)ptr)->base = val; return(val);}
  5347. static void pulse_train_reset(mus_any *ptr)
  5348. {
  5349. sw *gen = (sw *)ptr;
  5350. gen->phase = TWO_PI;
  5351. gen->current_value = 0.0;
  5352. }
  5353. static mus_any_class PULSE_TRAIN_CLASS = {
  5354. MUS_PULSE_TRAIN,
  5355. (char *)S_pulse_train,
  5356. &free_sw,
  5357. &describe_sw,
  5358. &sw_equalp,
  5359. 0, 0, 0, 0,
  5360. &sw_freq,
  5361. &sw_set_freq,
  5362. &sw_phase,
  5363. &sw_set_phase,
  5364. &pulse_train_scaler,
  5365. &pulse_train_set_scaler,
  5366. &sw_increment,
  5367. &sw_set_increment,
  5368. &run_pulse_train,
  5369. MUS_NOT_SPECIAL,
  5370. NULL, 0,
  5371. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  5372. 0, 0, 0, 0, 0, 0, 0,
  5373. 0, 0, 0, 0,
  5374. &pulse_train_reset,
  5375. 0, &sw_copy
  5376. };
  5377. mus_any *mus_make_pulse_train(mus_float_t freq, mus_float_t amp, mus_float_t phase) /* TWO_PI initial phase, normally */
  5378. {
  5379. sw *gen;
  5380. gen = (sw *)malloc(sizeof(sw));
  5381. gen->core = &PULSE_TRAIN_CLASS;
  5382. if (freq < 0.0) freq = -freq;
  5383. gen->freq = mus_hz_to_radians(freq);
  5384. gen->base = amp;
  5385. gen->phase = phase;
  5386. gen->current_value = 0.0;
  5387. return((mus_any *)gen);
  5388. }
  5389. /* ---------------- rand, rand_interp ---------------- */
  5390. typedef struct {
  5391. mus_any_class *core;
  5392. mus_float_t freq, phase, base, incr, norm;
  5393. mus_float_t output;
  5394. mus_float_t *distribution;
  5395. int distribution_size;
  5396. mus_float_t (*ran_unmod)(mus_any *ptr);
  5397. } noi;
  5398. /* rand taken from the ANSI C standard (essentially the same as the Cmix form used earlier) */
  5399. static unsigned long randx = 1;
  5400. #define INVERSE_MAX_RAND 0.0000610351563
  5401. #define INVERSE_MAX_RAND2 0.000030517579
  5402. void mus_set_rand_seed(unsigned long val) {randx = val;}
  5403. unsigned long mus_rand_seed(void) {return(randx);}
  5404. static mus_float_t next_random(void)
  5405. {
  5406. randx = randx * 1103515245 + 12345;
  5407. return((mus_float_t)((unsigned int)(randx >> 16) & 32767));
  5408. }
  5409. mus_float_t mus_random(mus_float_t amp) /* -amp to amp as mus_float_t */
  5410. {
  5411. return(amp * (next_random() * INVERSE_MAX_RAND - 1.0));
  5412. }
  5413. mus_float_t mus_frandom(mus_float_t amp) /* 0.0 to amp as mus_float_t */
  5414. {
  5415. return(amp * next_random() * INVERSE_MAX_RAND2);
  5416. }
  5417. int mus_irandom(int amp)
  5418. {
  5419. return((int)(amp * next_random() * INVERSE_MAX_RAND2));
  5420. }
  5421. static mus_float_t random_any(noi *gen) /* -amp to amp possibly through distribution */
  5422. {
  5423. if (gen->distribution)
  5424. return(gen->base * mus_array_interp(gen->distribution,
  5425. next_random() * INVERSE_MAX_RAND2 * gen->distribution_size,
  5426. gen->distribution_size));
  5427. return(gen->base * (next_random() * INVERSE_MAX_RAND - 1.0));
  5428. }
  5429. mus_float_t mus_rand(mus_any *ptr, mus_float_t fm)
  5430. {
  5431. noi *gen = (noi *)ptr;
  5432. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5433. {
  5434. gen->phase = fmod(gen->phase, TWO_PI);
  5435. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5436. gen->output = random_any(gen);
  5437. }
  5438. gen->phase += (gen->freq + fm);
  5439. return(gen->output);
  5440. }
  5441. static mus_float_t zero_unmodulated(mus_any *ptr) {return(0.0);}
  5442. mus_float_t mus_rand_unmodulated(mus_any *ptr)
  5443. {
  5444. noi *gen = (noi *)ptr;
  5445. if (gen->phase >= TWO_PI)
  5446. {
  5447. gen->phase -= TWO_PI;
  5448. gen->output = random_any(gen);
  5449. }
  5450. gen->phase += gen->freq;
  5451. return(gen->output);
  5452. }
  5453. mus_float_t mus_rand_interp(mus_any *ptr, mus_float_t fm)
  5454. {
  5455. /* fm can change the increment step during a ramp */
  5456. noi *gen = (noi *)ptr;
  5457. gen->output += gen->incr;
  5458. if (gen->output > gen->base)
  5459. gen->output = gen->base;
  5460. else
  5461. {
  5462. if (gen->output < -gen->base)
  5463. gen->output = -gen->base;
  5464. }
  5465. if ((gen->phase >= TWO_PI) || (gen->phase < 0.0))
  5466. {
  5467. gen->phase = fmod(gen->phase, TWO_PI);
  5468. if (gen->phase < 0.0) gen->phase += TWO_PI;
  5469. gen->incr = (random_any(gen) - gen->output) / (ceil(TWO_PI / (gen->freq + fm)));
  5470. }
  5471. gen->phase += (gen->freq + fm);
  5472. return(gen->output);
  5473. }
  5474. mus_float_t mus_rand_interp_unmodulated(mus_any *ptr)
  5475. {
  5476. return(((noi *)ptr)->ran_unmod(ptr));
  5477. }
  5478. mus_float_t (*mus_rand_interp_unmodulated_function(mus_any *g))(mus_any *gen);
  5479. mus_float_t (*mus_rand_interp_unmodulated_function(mus_any *g))(mus_any *gen)
  5480. {
  5481. if (mus_is_rand_interp(g))
  5482. return(((noi *)g)->ran_unmod);
  5483. return(NULL);
  5484. }
  5485. static mus_float_t rand_interp_unmodulated_with_distribution(mus_any *ptr)
  5486. {
  5487. noi *gen = (noi *)ptr;
  5488. gen->output += gen->incr;
  5489. if (gen->phase >= TWO_PI)
  5490. {
  5491. gen->phase -= TWO_PI;
  5492. gen->incr = (random_any(gen) - gen->output) / (ceil(TWO_PI / gen->freq));
  5493. }
  5494. gen->phase += gen->freq;
  5495. return(gen->output);
  5496. }
  5497. static mus_float_t rand_interp_unmodulated(mus_any *ptr)
  5498. {
  5499. noi *gen = (noi *)ptr;
  5500. gen->output += gen->incr;
  5501. gen->phase += gen->freq;
  5502. if (gen->phase >= TWO_PI)
  5503. {
  5504. gen->phase -= TWO_PI;
  5505. randx = randx * 1103515245 + 12345;
  5506. gen->incr = ((gen->base * ((mus_float_t)((unsigned int)(randx >> 16) & 32767) * INVERSE_MAX_RAND - 1.0)) - gen->output) * gen->norm;
  5507. }
  5508. return(gen->output);
  5509. }
  5510. static mus_float_t run_rand(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rand(ptr, fm));}
  5511. static mus_float_t run_rand_interp(mus_any *ptr, mus_float_t fm, mus_float_t unused) {return(mus_rand_interp(ptr, fm));}
  5512. bool mus_is_rand(mus_any *ptr)
  5513. {
  5514. return((ptr) &&
  5515. (ptr->core->type == MUS_RAND));
  5516. }
  5517. bool mus_is_rand_interp(mus_any *ptr)
  5518. {
  5519. return((ptr) &&
  5520. (ptr->core->type == MUS_RAND_INTERP));
  5521. }
  5522. static void free_noi(mus_any *ptr) {free(ptr);}
  5523. static mus_any *noi_copy(mus_any *ptr)
  5524. {
  5525. noi *g;
  5526. g = (noi *)malloc(sizeof(noi));
  5527. memcpy((void *)g, (void *)ptr, sizeof(noi));
  5528. /* if ptr->distribution, it comes from elsewhere -- we don't touch it here,
  5529. * and in clm2xen, we merely wrap it.
  5530. */
  5531. return((mus_any *)g);
  5532. }
  5533. static mus_float_t noi_freq(mus_any *ptr) {return(mus_radians_to_hz(((noi *)ptr)->freq));}
  5534. static mus_float_t noi_set_freq(mus_any *ptr, mus_float_t val)
  5535. {
  5536. if (val < 0.0) val = -val;
  5537. ((noi *)ptr)->freq = mus_hz_to_radians(val);
  5538. return(val);
  5539. }
  5540. static mus_float_t interp_noi_set_freq(mus_any *ptr, mus_float_t val)
  5541. {
  5542. noi *gen = (noi *)ptr;
  5543. if (val < 0.0) val = -val;
  5544. gen->freq = mus_hz_to_radians(val);
  5545. if (gen->freq != 0.0)
  5546. gen->norm = 1.0 / (ceil(TWO_PI / gen->freq));
  5547. return(val);
  5548. }
  5549. static mus_float_t noi_increment(mus_any *ptr) {return(((noi *)ptr)->freq);}
  5550. static mus_float_t noi_set_increment(mus_any *ptr, mus_float_t val) {((noi *)ptr)->freq = val; return(val);}
  5551. static mus_float_t noi_incr(mus_any *ptr) {return(((noi *)ptr)->incr);}
  5552. static mus_float_t noi_set_incr(mus_any *ptr, mus_float_t val) {((noi *)ptr)->incr = val; return(val);}
  5553. static mus_float_t noi_phase(mus_any *ptr) {return(fmod(((noi *)ptr)->phase, TWO_PI));}
  5554. static mus_float_t noi_set_phase(mus_any *ptr, mus_float_t val) {((noi *)ptr)->phase = val; return(val);}
  5555. static mus_float_t noi_scaler(mus_any *ptr) {return(((noi *)ptr)->base);}
  5556. static mus_float_t noi_set_scaler(mus_any *ptr, mus_float_t val) {((noi *)ptr)->base = val; return(val);} /* rand, not rand-interp */
  5557. static mus_float_t *noi_data(mus_any *ptr) {return(((noi *)ptr)->distribution);}
  5558. static mus_long_t noi_length(mus_any *ptr) {return(((noi *)ptr)->distribution_size);}
  5559. static mus_float_t randi_set_scaler(mus_any *ptr, mus_float_t val)
  5560. {
  5561. noi *gen = (noi *)ptr;
  5562. if (val == 0.0)
  5563. gen->ran_unmod = zero_unmodulated;
  5564. else
  5565. {
  5566. if (gen->base == 0.0)
  5567. {
  5568. if (gen->distribution)
  5569. gen->ran_unmod = rand_interp_unmodulated_with_distribution;
  5570. else gen->ran_unmod = rand_interp_unmodulated;
  5571. }
  5572. }
  5573. gen->base = val;
  5574. return(val);
  5575. }
  5576. static void noi_reset(mus_any *ptr)
  5577. {
  5578. noi *gen = (noi *)ptr;
  5579. gen->phase = 0.0;
  5580. gen->output = 0.0;
  5581. }
  5582. static bool noi_equalp(mus_any *p1, mus_any *p2)
  5583. {
  5584. noi *g1 = (noi *)p1;
  5585. noi *g2 = (noi *)p2;
  5586. return((p1 == p2) ||
  5587. ((g1) && (g2) &&
  5588. (g1->core->type == g2->core->type) &&
  5589. (g1->freq == g2->freq) &&
  5590. (g1->phase == g2->phase) &&
  5591. (g1->output == g2->output) &&
  5592. (g1->incr == g2->incr) &&
  5593. (g1->base == g2->base) &&
  5594. (g1->distribution_size == g2->distribution_size) &&
  5595. (g1->distribution == g2->distribution)));
  5596. }
  5597. static char *describe_noi(mus_any *ptr)
  5598. {
  5599. noi *gen = (noi *)ptr;
  5600. char *describe_buffer;
  5601. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  5602. if (mus_is_rand(ptr))
  5603. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f%s",
  5604. mus_name(ptr),
  5605. mus_frequency(ptr),
  5606. mus_phase(ptr),
  5607. mus_scaler(ptr),
  5608. (gen->distribution) ? ", with distribution envelope" : "");
  5609. else
  5610. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s freq: %.3fHz, phase: %.3f, amp: %.3f, incr: %.3f, curval: %.3f%s",
  5611. mus_name(ptr),
  5612. mus_frequency(ptr),
  5613. mus_phase(ptr),
  5614. mus_scaler(ptr),
  5615. gen->incr,
  5616. gen->output,
  5617. (gen->distribution) ? ", with distribution envelope" : "");
  5618. return(describe_buffer);
  5619. }
  5620. static mus_any_class RAND_CLASS = {
  5621. MUS_RAND,
  5622. (char *)S_rand,
  5623. &free_noi,
  5624. &describe_noi,
  5625. &noi_equalp,
  5626. &noi_data, 0,
  5627. &noi_length, 0,
  5628. &noi_freq,
  5629. &noi_set_freq,
  5630. &noi_phase,
  5631. &noi_set_phase,
  5632. &noi_scaler,
  5633. &noi_set_scaler,
  5634. &noi_increment, /* this is the phase increment, not the incr field */
  5635. &noi_set_increment,
  5636. &run_rand,
  5637. MUS_NOT_SPECIAL,
  5638. NULL, 0,
  5639. &noi_incr, &noi_set_incr,
  5640. 0, 0, 0, 0, 0, 0, 0, 0,
  5641. 0, 0, 0, 0, 0, 0, 0,
  5642. 0, 0, 0, 0,
  5643. &noi_reset,
  5644. 0, &noi_copy
  5645. };
  5646. static mus_any_class RAND_INTERP_CLASS = {
  5647. MUS_RAND_INTERP,
  5648. (char *)S_rand_interp,
  5649. &free_noi,
  5650. &describe_noi,
  5651. &noi_equalp,
  5652. &noi_data, 0,
  5653. &noi_length, 0,
  5654. &noi_freq,
  5655. &interp_noi_set_freq,
  5656. &noi_phase,
  5657. &noi_set_phase,
  5658. &noi_scaler,
  5659. &randi_set_scaler,
  5660. &noi_increment, /* phase increment, not incr field */
  5661. &noi_set_increment,
  5662. &run_rand_interp,
  5663. MUS_NOT_SPECIAL,
  5664. NULL, 0,
  5665. &noi_incr, &noi_set_incr, /* incr field == mus_offset method */
  5666. 0, 0, 0, 0, 0, 0, 0, 0,
  5667. 0, 0, 0, 0, 0, 0, 0,
  5668. 0, 0, 0, 0,
  5669. &noi_reset,
  5670. 0, &noi_copy
  5671. };
  5672. mus_any *mus_make_rand(mus_float_t freq, mus_float_t base)
  5673. {
  5674. noi *gen;
  5675. gen = (noi *)calloc(1, sizeof(noi));
  5676. gen->core = &RAND_CLASS;
  5677. if (freq < 0.0) freq = -freq;
  5678. gen->freq = mus_hz_to_radians(freq);
  5679. gen->base = base;
  5680. gen->incr = 0.0;
  5681. gen->output = random_any(gen); /* this was always starting at 0.0 (changed 23-Dec-06) */
  5682. return((mus_any *)gen);
  5683. }
  5684. mus_any *mus_make_rand_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size)
  5685. {
  5686. noi *gen;
  5687. gen = (noi *)mus_make_rand(freq, base);
  5688. gen->distribution = distribution;
  5689. gen->distribution_size = distribution_size;
  5690. gen->output = random_any(gen);
  5691. return((mus_any *)gen);
  5692. }
  5693. mus_any *mus_make_rand_interp(mus_float_t freq, mus_float_t base)
  5694. {
  5695. noi *gen;
  5696. gen = (noi *)calloc(1, sizeof(noi));
  5697. gen->core = &RAND_INTERP_CLASS;
  5698. /* gen->distribution = NULL; */
  5699. if (freq < 0.0) freq = -freq;
  5700. gen->freq = mus_hz_to_radians(freq);
  5701. gen->base = base;
  5702. gen->incr = mus_random(base) * freq / sampling_rate;
  5703. gen->output = 0.0;
  5704. if (gen->freq != 0.0)
  5705. gen->norm = 1.0 / (ceil(TWO_PI / gen->freq));
  5706. else gen->norm = 1.0;
  5707. gen->ran_unmod = ((base == 0.0) ? zero_unmodulated : rand_interp_unmodulated);
  5708. return((mus_any *)gen);
  5709. }
  5710. mus_any *mus_make_rand_interp_with_distribution(mus_float_t freq, mus_float_t base, mus_float_t *distribution, int distribution_size)
  5711. {
  5712. noi *gen;
  5713. gen = (noi *)mus_make_rand_interp(freq, base);
  5714. gen->distribution = distribution;
  5715. gen->distribution_size = distribution_size;
  5716. gen->ran_unmod = ((base == 0.0) ? zero_unmodulated : rand_interp_unmodulated_with_distribution);
  5717. return((mus_any *)gen);
  5718. }
  5719. /* ---------------- simple filters ---------------- */
  5720. typedef struct {
  5721. mus_any_class *core;
  5722. mus_float_t xs[3];
  5723. mus_float_t ys[3];
  5724. mus_float_t x1, x2, y1, y2;
  5725. } smpflt;
  5726. static void free_smpflt(mus_any *ptr) {free(ptr);}
  5727. static mus_any *smpflt_copy(mus_any *ptr)
  5728. {
  5729. smpflt *g;
  5730. g = (smpflt *)malloc(sizeof(smpflt));
  5731. memcpy((void *)g, (void *)ptr, sizeof(smpflt));
  5732. return((mus_any *)g);
  5733. }
  5734. static bool smpflt_equalp(mus_any *p1, mus_any *p2)
  5735. {
  5736. smpflt *g1 = (smpflt *)p1;
  5737. smpflt *g2 = (smpflt *)p2;
  5738. return((p1 == p2) ||
  5739. ((g1->core->type == g2->core->type) &&
  5740. (g1->xs[0] == g2->xs[0]) &&
  5741. (g1->xs[1] == g2->xs[1]) &&
  5742. (g1->xs[2] == g2->xs[2]) &&
  5743. (g1->ys[1] == g2->ys[1]) &&
  5744. (g1->ys[2] == g2->ys[2]) &&
  5745. (g1->x1 == g2->x1) &&
  5746. (g1->x2 == g2->x2) &&
  5747. (g1->y1 == g2->y1) &&
  5748. (g1->y2 == g2->y2)));
  5749. }
  5750. static char *describe_smpflt(mus_any *ptr)
  5751. {
  5752. smpflt *gen = (smpflt *)ptr;
  5753. char *describe_buffer;
  5754. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  5755. switch (gen->core->type)
  5756. {
  5757. case MUS_ONE_ZERO:
  5758. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, a1: %.3f, x1: %.3f",
  5759. mus_name(ptr),
  5760. gen->xs[0], gen->xs[1], gen->x1);
  5761. break;
  5762. case MUS_ONE_POLE:
  5763. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, b1: %.3f, y1: %.3f",
  5764. mus_name(ptr),
  5765. gen->xs[0], gen->ys[1], gen->y1);
  5766. break;
  5767. case MUS_TWO_ZERO:
  5768. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, a1: %.3f, a2: %.3f, x1: %.3f, x2: %.3f",
  5769. mus_name(ptr),
  5770. gen->xs[0], gen->xs[1], gen->xs[2], gen->x1, gen->x2);
  5771. break;
  5772. case MUS_TWO_POLE:
  5773. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s a0: %.3f, b1: %.3f, b2: %.3f, y1: %.3f, y2: %.3f",
  5774. mus_name(ptr),
  5775. gen->xs[0], gen->ys[1], gen->ys[2], gen->y1, gen->y2);
  5776. break;
  5777. }
  5778. return(describe_buffer);
  5779. }
  5780. mus_float_t mus_one_zero(mus_any *ptr, mus_float_t input)
  5781. {
  5782. smpflt *gen = (smpflt *)ptr;
  5783. mus_float_t result;
  5784. result = (gen->xs[0] * input) + (gen->xs[1] * gen->x1);
  5785. gen->x1 = input;
  5786. return(result);
  5787. }
  5788. static mus_float_t run_one_zero(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_one_zero(ptr, input));}
  5789. static mus_long_t one_length(mus_any *ptr) {return(1);}
  5790. static mus_long_t two_length(mus_any *ptr) {return(2);}
  5791. static mus_float_t smp_xcoeff(mus_any *ptr, int index) {return(((smpflt *)ptr)->xs[index]);}
  5792. static mus_float_t smp_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {((smpflt *)ptr)->xs[index] = val; return(val);}
  5793. static mus_float_t smp_ycoeff(mus_any *ptr, int index) {return(((smpflt *)ptr)->ys[index]);}
  5794. static mus_float_t smp_set_ycoeff(mus_any *ptr, int index, mus_float_t val) {((smpflt *)ptr)->ys[index] = val; return(val);}
  5795. static mus_float_t *smp_xcoeffs(mus_any *ptr) {return(((smpflt *)ptr)->xs);}
  5796. static mus_float_t *smp_ycoeffs(mus_any *ptr) {return(((smpflt *)ptr)->ys);}
  5797. static void smp_scl(mus_any *ptr, mus_float_t scl) {smpflt *g = (smpflt *)ptr; g->xs[0] *= scl; g->xs[1] *= scl;}
  5798. static void smpflt_reset(mus_any *ptr)
  5799. {
  5800. smpflt *gen = (smpflt *)ptr;
  5801. gen->x1 = 0.0;
  5802. gen->x2 = 0.0;
  5803. gen->y1 = 0.0;
  5804. gen->y2 = 0.0;
  5805. }
  5806. static mus_any_class ONE_ZERO_CLASS = {
  5807. MUS_ONE_ZERO,
  5808. (char *)S_one_zero,
  5809. &free_smpflt,
  5810. &describe_smpflt,
  5811. &smpflt_equalp,
  5812. 0, 0,
  5813. &one_length, 0,
  5814. 0, 0, 0, 0,
  5815. 0, 0,
  5816. 0, 0,
  5817. &run_one_zero,
  5818. MUS_SIMPLE_FILTER,
  5819. NULL, 0,
  5820. 0, 0,
  5821. 0, 0,
  5822. &smp_xcoeff, &smp_set_xcoeff,
  5823. 0, 0, 0, 0,
  5824. 0, 0, 0, 0, 0, 0, 0,
  5825. 0, 0,
  5826. &smp_xcoeffs, &smp_ycoeffs,
  5827. &smpflt_reset,
  5828. 0, &smpflt_copy
  5829. };
  5830. mus_any *mus_make_one_zero(mus_float_t a0, mus_float_t a1)
  5831. {
  5832. smpflt *gen;
  5833. gen = (smpflt *)calloc(1, sizeof(smpflt));
  5834. gen->core = &ONE_ZERO_CLASS;
  5835. gen->xs[0] = a0;
  5836. gen->xs[1] = a1;
  5837. return((mus_any *)gen);
  5838. }
  5839. bool mus_is_one_zero(mus_any *ptr)
  5840. {
  5841. return((ptr) &&
  5842. (ptr->core->type == MUS_ONE_ZERO));
  5843. }
  5844. mus_float_t mus_one_pole(mus_any *ptr, mus_float_t input)
  5845. {
  5846. smpflt *gen = (smpflt *)ptr;
  5847. gen->y1 = (gen->xs[0] * input) - (gen->ys[1] * gen->y1);
  5848. return(gen->y1);
  5849. }
  5850. /* incrementer: (make-one-pole 1.0 -1.0) */
  5851. static mus_float_t run_one_pole(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_one_pole(ptr, input));}
  5852. static mus_any_class ONE_POLE_CLASS = {
  5853. MUS_ONE_POLE,
  5854. (char *)S_one_pole,
  5855. &free_smpflt,
  5856. &describe_smpflt,
  5857. &smpflt_equalp,
  5858. 0, 0,
  5859. &one_length, 0,
  5860. 0, 0, 0, 0,
  5861. 0, 0, 0, 0,
  5862. &run_one_pole,
  5863. MUS_SIMPLE_FILTER,
  5864. NULL, 0,
  5865. 0, 0, 0, 0,
  5866. &smp_xcoeff, &smp_set_xcoeff,
  5867. 0, 0, 0, 0,
  5868. 0, 0, 0, 0, 0, 0, 0,
  5869. &smp_ycoeff, &smp_set_ycoeff,
  5870. &smp_xcoeffs, &smp_ycoeffs,
  5871. &smpflt_reset,
  5872. 0, &smpflt_copy
  5873. };
  5874. mus_any *mus_make_one_pole(mus_float_t a0, mus_float_t b1)
  5875. {
  5876. smpflt *gen;
  5877. gen = (smpflt *)calloc(1, sizeof(smpflt));
  5878. gen->core = &ONE_POLE_CLASS;
  5879. gen->xs[0] = a0;
  5880. gen->ys[1] = b1;
  5881. return((mus_any *)gen);
  5882. }
  5883. bool mus_is_one_pole(mus_any *ptr)
  5884. {
  5885. return((ptr) &&
  5886. (ptr->core->type == MUS_ONE_POLE));
  5887. }
  5888. mus_float_t mus_two_zero(mus_any *ptr, mus_float_t input)
  5889. {
  5890. smpflt *gen = (smpflt *)ptr;
  5891. mus_float_t result;
  5892. result = (gen->xs[0] * input) + (gen->xs[1] * gen->x1) + (gen->xs[2] * gen->x2);
  5893. gen->x2 = gen->x1;
  5894. gen->x1 = input;
  5895. return(result);
  5896. }
  5897. static mus_float_t run_two_zero(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_two_zero(ptr, input));}
  5898. static mus_float_t two_zero_radius(mus_any *ptr)
  5899. {
  5900. smpflt *gen = (smpflt *)ptr;
  5901. return(sqrt(gen->xs[2]));
  5902. }
  5903. static mus_float_t two_zero_set_radius(mus_any *ptr, mus_float_t new_radius)
  5904. {
  5905. smpflt *gen = (smpflt *)ptr;
  5906. gen->xs[1] = -2.0 * new_radius * cos(mus_hz_to_radians(mus_frequency(ptr)));
  5907. gen->xs[2] = new_radius * new_radius;
  5908. return(new_radius);
  5909. }
  5910. static mus_float_t two_zero_frequency(mus_any *ptr)
  5911. {
  5912. smpflt *gen = (smpflt *)ptr;
  5913. return(mus_radians_to_hz(acos(gen->xs[1] / (-2.0 * two_zero_radius(ptr)))));
  5914. }
  5915. static mus_float_t two_zero_set_frequency(mus_any *ptr, mus_float_t new_freq)
  5916. {
  5917. smpflt *gen = (smpflt *)ptr;
  5918. gen->xs[1] = -2.0 * mus_scaler(ptr) * cos(mus_hz_to_radians(new_freq));
  5919. return(new_freq);
  5920. }
  5921. static mus_any_class TWO_ZERO_CLASS = {
  5922. MUS_TWO_ZERO,
  5923. (char *)S_two_zero,
  5924. &free_smpflt,
  5925. &describe_smpflt,
  5926. &smpflt_equalp,
  5927. 0, 0,
  5928. &two_length, 0,
  5929. &two_zero_frequency, &two_zero_set_frequency,
  5930. 0, 0,
  5931. &two_zero_radius, &two_zero_set_radius,
  5932. 0, 0,
  5933. &run_two_zero,
  5934. MUS_SIMPLE_FILTER,
  5935. NULL, 0,
  5936. 0, 0, 0, 0,
  5937. &smp_xcoeff, &smp_set_xcoeff,
  5938. 0, 0, 0, 0,
  5939. 0, 0, 0, 0, 0, 0, 0,
  5940. 0, 0,
  5941. &smp_xcoeffs, &smp_ycoeffs,
  5942. &smpflt_reset,
  5943. 0, &smpflt_copy
  5944. };
  5945. mus_any *mus_make_two_zero(mus_float_t a0, mus_float_t a1, mus_float_t a2)
  5946. {
  5947. smpflt *gen;
  5948. gen = (smpflt *)calloc(1, sizeof(smpflt));
  5949. gen->core = &TWO_ZERO_CLASS;
  5950. gen->xs[0] = a0;
  5951. gen->xs[1] = a1;
  5952. gen->xs[2] = a2;
  5953. return((mus_any *)gen);
  5954. }
  5955. bool mus_is_two_zero(mus_any *ptr)
  5956. {
  5957. return((ptr) &&
  5958. (ptr->core->type == MUS_TWO_ZERO));
  5959. }
  5960. mus_any *mus_make_two_zero_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius)
  5961. {
  5962. return(mus_make_two_zero(1.0, -2.0 * radius * cos(mus_hz_to_radians(frequency)), radius * radius));
  5963. }
  5964. mus_float_t mus_two_pole(mus_any *ptr, mus_float_t input)
  5965. {
  5966. smpflt *gen = (smpflt *)ptr;
  5967. mus_float_t result;
  5968. result = (gen->xs[0] * input) - (gen->ys[1] * gen->y1) - (gen->ys[2] * gen->y2);
  5969. gen->y2 = gen->y1;
  5970. gen->y1 = result;
  5971. return(result);
  5972. }
  5973. static mus_float_t run_two_pole(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_two_pole(ptr, input));}
  5974. static mus_float_t two_pole_radius(mus_any *ptr)
  5975. {
  5976. smpflt *gen = (smpflt *)ptr;
  5977. return(sqrt(gen->ys[2]));
  5978. }
  5979. static mus_float_t two_pole_set_radius(mus_any *ptr, mus_float_t new_radius)
  5980. {
  5981. smpflt *gen = (smpflt *)ptr;
  5982. gen->ys[1] = -2.0 * new_radius * cos(mus_hz_to_radians(mus_frequency(ptr)));
  5983. gen->ys[2] = new_radius * new_radius;
  5984. return(new_radius);
  5985. }
  5986. static mus_float_t two_pole_frequency(mus_any *ptr)
  5987. {
  5988. smpflt *gen = (smpflt *)ptr;
  5989. return(mus_radians_to_hz(acos(gen->ys[1] / (-2.0 * two_pole_radius(ptr)))));
  5990. }
  5991. static mus_float_t two_pole_set_frequency(mus_any *ptr, mus_float_t new_freq)
  5992. {
  5993. smpflt *gen = (smpflt *)ptr;
  5994. gen->ys[1] = -2.0 * mus_scaler(ptr) * cos(mus_hz_to_radians(new_freq));
  5995. return(new_freq);
  5996. }
  5997. static mus_any_class TWO_POLE_CLASS = {
  5998. MUS_TWO_POLE,
  5999. (char *)S_two_pole,
  6000. &free_smpflt,
  6001. &describe_smpflt,
  6002. &smpflt_equalp,
  6003. 0, 0,
  6004. &two_length, 0,
  6005. &two_pole_frequency, &two_pole_set_frequency,
  6006. 0, 0,
  6007. &two_pole_radius, &two_pole_set_radius,
  6008. 0, 0,
  6009. &run_two_pole,
  6010. MUS_SIMPLE_FILTER,
  6011. NULL, 0,
  6012. 0, 0, 0, 0,
  6013. &smp_xcoeff, &smp_set_xcoeff,
  6014. 0, 0, 0, 0,
  6015. 0, 0, 0, 0, 0, 0, 0,
  6016. &smp_ycoeff, &smp_set_ycoeff,
  6017. &smp_xcoeffs, &smp_ycoeffs,
  6018. &smpflt_reset,
  6019. 0, &smpflt_copy
  6020. };
  6021. mus_any *mus_make_two_pole(mus_float_t a0, mus_float_t b1, mus_float_t b2)
  6022. {
  6023. smpflt *gen;
  6024. gen = (smpflt *)calloc(1, sizeof(smpflt));
  6025. gen->core = &TWO_POLE_CLASS;
  6026. gen->xs[0] = a0;
  6027. gen->ys[1] = b1;
  6028. gen->ys[2] = b2;
  6029. return((mus_any *)gen);
  6030. }
  6031. bool mus_is_two_pole(mus_any *ptr)
  6032. {
  6033. return((ptr) &&
  6034. (ptr->core->type == MUS_TWO_POLE));
  6035. }
  6036. mus_any *mus_make_two_pole_from_frequency_and_radius(mus_float_t frequency, mus_float_t radius)
  6037. {
  6038. return(mus_make_two_pole(1.0, -2.0 * radius * cos(mus_hz_to_radians(frequency)), radius * radius));
  6039. }
  6040. /* ---------------- formant ---------------- */
  6041. typedef struct {
  6042. mus_any_class *core;
  6043. mus_float_t frequency, radius;
  6044. mus_float_t x1, x2, y1, y2;
  6045. mus_float_t rr, gain, fdbk;
  6046. } frm;
  6047. static void free_frm(mus_any *ptr) {free(ptr);}
  6048. static mus_any *frm_copy(mus_any *ptr)
  6049. {
  6050. frm *g;
  6051. g = (frm *)malloc(sizeof(frm));
  6052. memcpy((void *)g, (void *)ptr, sizeof(frm));
  6053. return((mus_any *)g);
  6054. }
  6055. bool mus_is_formant(mus_any *ptr)
  6056. {
  6057. return((ptr) &&
  6058. (ptr->core->type == MUS_FORMANT));
  6059. }
  6060. static void frm_reset(mus_any *ptr)
  6061. {
  6062. frm *gen = (frm *)ptr;
  6063. gen->x1 = 0.0;
  6064. gen->x2 = 0.0;
  6065. gen->y1 = 0.0;
  6066. gen->y2 = 0.0;
  6067. }
  6068. static bool frm_equalp(mus_any *p1, mus_any *p2)
  6069. {
  6070. frm *g1 = (frm *)p1;
  6071. frm *g2 = (frm *)p2;
  6072. return((p1 == p2) ||
  6073. ((g1->core->type == g2->core->type) &&
  6074. (g1->radius == g2->radius) &&
  6075. (g1->frequency == g2->frequency) &&
  6076. (g1->x1 == g2->x1) &&
  6077. (g1->x2 == g2->x2) &&
  6078. (g1->y1 == g2->y1) &&
  6079. (g1->y2 == g2->y2)));
  6080. }
  6081. static char *describe_formant(mus_any *ptr)
  6082. {
  6083. frm *gen = (frm *)ptr;
  6084. char *describe_buffer;
  6085. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  6086. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, radius: %.3f",
  6087. mus_name(ptr),
  6088. mus_radians_to_hz(gen->frequency),
  6089. gen->radius);
  6090. return(describe_buffer);
  6091. }
  6092. mus_float_t mus_formant(mus_any *ptr, mus_float_t input)
  6093. {
  6094. frm *gen = (frm *)ptr;
  6095. mus_float_t x0, y0;
  6096. x0 = gen->gain * input;
  6097. y0 = x0 - gen->x2 + (gen->fdbk * gen->y1) - (gen->rr * gen->y2);
  6098. gen->y2 = gen->y1;
  6099. gen->y1 = y0;
  6100. gen->x2 = gen->x1;
  6101. gen->x1 = x0;
  6102. return(y0);
  6103. }
  6104. static mus_float_t run_formant(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_formant(ptr, input));}
  6105. static void mus_set_formant_radius_and_frequency_in_radians(mus_any *ptr, mus_float_t radius, mus_float_t freq_in_radians)
  6106. {
  6107. frm *gen = (frm *)ptr;
  6108. gen->radius = radius;
  6109. gen->frequency = freq_in_radians;
  6110. gen->rr = radius * radius;
  6111. gen->gain = (1.0 - gen->rr) * 0.5;
  6112. gen->fdbk = 2.0 * radius * cos(freq_in_radians);
  6113. }
  6114. void mus_set_formant_radius_and_frequency(mus_any *ptr, mus_float_t radius, mus_float_t freq_in_hz)
  6115. {
  6116. mus_set_formant_radius_and_frequency_in_radians(ptr, radius, mus_hz_to_radians(freq_in_hz));
  6117. }
  6118. static mus_float_t formant_frequency(mus_any *ptr) {return(mus_radians_to_hz(((frm *)ptr)->frequency));}
  6119. mus_float_t mus_set_formant_frequency(mus_any *ptr, mus_float_t freq_in_hz)
  6120. {
  6121. frm *gen = (frm *)ptr;
  6122. mus_float_t fw;
  6123. fw = mus_hz_to_radians(freq_in_hz);
  6124. gen->frequency = fw;
  6125. gen->fdbk = 2.0 * gen->radius * cos(fw);
  6126. return(freq_in_hz);
  6127. }
  6128. mus_float_t mus_formant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians)
  6129. {
  6130. frm *gen = (frm *)ptr;
  6131. if (gen->frequency != freq_in_radians)
  6132. {
  6133. gen->frequency = freq_in_radians;
  6134. gen->fdbk = 2.0 * gen->radius * cos(freq_in_radians);
  6135. }
  6136. return(mus_formant(ptr, input));
  6137. }
  6138. static mus_float_t formant_radius(mus_any *ptr) {return(((frm *)ptr)->radius);}
  6139. static mus_float_t formant_set_radius(mus_any *ptr, mus_float_t val)
  6140. {
  6141. mus_set_formant_radius_and_frequency_in_radians(ptr, val, ((frm *)ptr)->frequency);
  6142. return(val);
  6143. }
  6144. static mus_any_class FORMANT_CLASS = {
  6145. MUS_FORMANT,
  6146. (char *)S_formant,
  6147. &free_frm,
  6148. &describe_formant,
  6149. &frm_equalp,
  6150. 0, 0,
  6151. &two_length, 0,
  6152. &formant_frequency, &mus_set_formant_frequency,
  6153. 0, 0,
  6154. &formant_radius, &formant_set_radius,
  6155. 0, 0,
  6156. &run_formant,
  6157. MUS_SIMPLE_FILTER,
  6158. NULL, 0,
  6159. 0, 0, 0, 0,
  6160. 0, 0,
  6161. 0, 0, 0, 0,
  6162. 0, 0, 0, 0, 0, 0, 0,
  6163. 0, 0, 0, 0,
  6164. &frm_reset,
  6165. 0, &frm_copy
  6166. };
  6167. mus_any *mus_make_formant(mus_float_t frequency, mus_float_t radius)
  6168. {
  6169. frm *gen;
  6170. gen = (frm *)calloc(1, sizeof(frm));
  6171. gen->core = &FORMANT_CLASS;
  6172. mus_set_formant_radius_and_frequency((mus_any *)gen, radius, frequency);
  6173. return((mus_any *)gen);
  6174. }
  6175. /* ---------------- formant-bank ---------------- */
  6176. typedef struct {
  6177. mus_any_class *core;
  6178. int size, mctr;
  6179. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain;
  6180. mus_float_t c1, c2;
  6181. mus_float_t (*one_input)(mus_any *fbank, mus_float_t inval);
  6182. mus_float_t (*many_inputs)(mus_any *fbank, mus_float_t *inval);
  6183. } frm_bank;
  6184. static void free_formant_bank(mus_any *ptr)
  6185. {
  6186. frm_bank *f = (frm_bank *)ptr;
  6187. if (f->x0) {free(f->x0); f->x0 = NULL;}
  6188. if (f->x1) {free(f->x1); f->x1 = NULL;}
  6189. if (f->x2) {free(f->x2); f->x2 = NULL;}
  6190. if (f->y0) {free(f->y0); f->y0 = NULL;}
  6191. if (f->y1) {free(f->y1); f->y1 = NULL;}
  6192. if (f->y2) {free(f->y2); f->y2 = NULL;}
  6193. if (f->rr) {free(f->rr); f->rr = NULL;}
  6194. if (f->fdbk) {free(f->fdbk); f->fdbk = NULL;}
  6195. if (f->gain) {free(f->gain); f->gain = NULL;}
  6196. free(ptr);
  6197. }
  6198. static mus_any *frm_bank_copy(mus_any *ptr)
  6199. {
  6200. frm_bank *g, *p;
  6201. int bytes;
  6202. p = (frm_bank *)ptr;
  6203. g = (frm_bank *)malloc(sizeof(frm_bank));
  6204. memcpy((void *)g, (void *)ptr, sizeof(frm_bank));
  6205. bytes = g->size * sizeof(mus_float_t);
  6206. g->x0 = (mus_float_t *)malloc(bytes);
  6207. memcpy((void *)(g->x0), (void *)(p->x0), bytes);
  6208. g->x1 = (mus_float_t *)malloc(bytes);
  6209. memcpy((void *)(g->x1), (void *)(p->x1), bytes);
  6210. g->x2 = (mus_float_t *)malloc(bytes);
  6211. memcpy((void *)(g->x2), (void *)(p->x2), bytes);
  6212. g->y0 = (mus_float_t *)malloc(bytes);
  6213. memcpy((void *)(g->y0), (void *)(p->y0), bytes);
  6214. g->y1 = (mus_float_t *)malloc(bytes);
  6215. memcpy((void *)(g->y1), (void *)(p->y1), bytes);
  6216. g->y2 = (mus_float_t *)malloc(bytes);
  6217. memcpy((void *)(g->y2), (void *)(p->y2), bytes);
  6218. g->rr = (mus_float_t *)malloc(bytes);
  6219. memcpy((void *)(g->rr), (void *)(p->rr), bytes);
  6220. g->fdbk = (mus_float_t *)malloc(bytes);
  6221. memcpy((void *)(g->fdbk), (void *)(p->fdbk), bytes);
  6222. g->gain = (mus_float_t *)malloc(bytes);
  6223. memcpy((void *)(g->gain), (void *)(p->gain), bytes);
  6224. return((mus_any *)g);
  6225. }
  6226. static mus_float_t run_formant_bank(mus_any *ptr, mus_float_t input, mus_float_t unused)
  6227. {
  6228. return(mus_formant_bank(ptr, input));
  6229. }
  6230. static mus_long_t formant_bank_length(mus_any *ptr)
  6231. {
  6232. return(((frm_bank *)ptr)->size);
  6233. }
  6234. static void formant_bank_reset(mus_any *ptr)
  6235. {
  6236. frm_bank *f = (frm_bank *)ptr;
  6237. int size;
  6238. size = f->size * sizeof(mus_float_t);
  6239. memset((void *)(f->x0), 0, size);
  6240. memset((void *)(f->x1), 0, size);
  6241. memset((void *)(f->x2), 0, size);
  6242. memset((void *)(f->y0), 0, size);
  6243. memset((void *)(f->y1), 0, size);
  6244. memset((void *)(f->y2), 0, size);
  6245. }
  6246. static bool formant_bank_equalp(mus_any *p1, mus_any *p2)
  6247. {
  6248. frm_bank *f1 = (frm_bank *)p1;
  6249. frm_bank *f2 = (frm_bank *)p2;
  6250. #if 0
  6251. int i, size;
  6252. #endif
  6253. if (f1 == f2) return(true);
  6254. if (f1->size != f2->size) return(false);
  6255. #if 0
  6256. size = f1->size;
  6257. for (i = 0; i < size; i++)
  6258. if (!frm_equalp(f1->gens[i], f2->gens[i]))
  6259. return(false);
  6260. #endif
  6261. /* now check the locals... */
  6262. return(true);
  6263. }
  6264. static char *describe_formant_bank(mus_any *ptr)
  6265. {
  6266. frm_bank *gen = (frm_bank *)ptr;
  6267. char *describe_buffer;
  6268. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  6269. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d", mus_name(ptr), gen->size);
  6270. return(describe_buffer);
  6271. }
  6272. mus_float_t mus_formant_bank(mus_any *fbank, mus_float_t inval)
  6273. {
  6274. frm_bank *bank = (frm_bank *)fbank;
  6275. return(bank->one_input(fbank, inval));
  6276. }
  6277. mus_float_t mus_formant_bank_with_inputs(mus_any *fbank, mus_float_t *inval)
  6278. {
  6279. frm_bank *bank = (frm_bank *)fbank;
  6280. return(bank->many_inputs(fbank, inval));
  6281. }
  6282. static mus_float_t fb_one_with_amps(mus_any *fbank, mus_float_t inval)
  6283. {
  6284. frm_bank *bank = (frm_bank *)fbank;
  6285. int i, size4;
  6286. mus_float_t sum = 0.0;
  6287. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain;
  6288. x0 = bank->x0;
  6289. x1 = bank->x1;
  6290. x2 = bank->x2;
  6291. y0 = bank->y0;
  6292. y1 = bank->y1;
  6293. y2 = bank->y2;
  6294. rr = bank->rr;
  6295. fdbk = bank->fdbk;
  6296. gain = bank->gain;
  6297. amps = bank->amps;
  6298. size4 = bank->size - 4;
  6299. i = 0;
  6300. while (i <= size4)
  6301. {
  6302. x0[i] = gain[i] * inval;
  6303. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6304. sum += amps[i] * y0[i];
  6305. i++;
  6306. x0[i] = gain[i] * inval;
  6307. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6308. sum += amps[i] * y0[i];
  6309. i++;
  6310. x0[i] = gain[i] * inval;
  6311. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6312. sum += amps[i] * y0[i];
  6313. i++;
  6314. x0[i] = gain[i] * inval;
  6315. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6316. sum += amps[i] * y0[i];
  6317. i++;
  6318. }
  6319. for (; i < bank->size; i++)
  6320. {
  6321. x0[i] = gain[i] * inval;
  6322. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6323. sum += amps[i] * y0[i];
  6324. }
  6325. bank->x2 = x1;
  6326. bank->x1 = x0;
  6327. bank->x0 = x2;
  6328. bank->y2 = y1;
  6329. bank->y1 = y0;
  6330. bank->y0 = y2;
  6331. return(sum);
  6332. }
  6333. static mus_float_t fb_one_without_amps(mus_any *fbank, mus_float_t inval)
  6334. {
  6335. frm_bank *bank = (frm_bank *)fbank;
  6336. int i;
  6337. mus_float_t sum = 0.0;
  6338. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *rr, *fdbk, *gain;
  6339. x0 = bank->x0;
  6340. x1 = bank->x1;
  6341. x2 = bank->x2;
  6342. y0 = bank->y0;
  6343. y1 = bank->y1;
  6344. y2 = bank->y2;
  6345. rr = bank->rr;
  6346. fdbk = bank->fdbk;
  6347. gain = bank->gain;
  6348. for (i = 0; i < bank->size; i++)
  6349. {
  6350. x0[i] = gain[i] * inval;
  6351. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6352. sum += y0[i];
  6353. }
  6354. bank->x2 = x1;
  6355. bank->x1 = x0;
  6356. bank->x0 = x2;
  6357. bank->y2 = y1;
  6358. bank->y1 = y0;
  6359. bank->y0 = y2;
  6360. return(sum);
  6361. }
  6362. static mus_float_t fb_many_with_amps(mus_any *fbank, mus_float_t *inval)
  6363. {
  6364. frm_bank *bank = (frm_bank *)fbank;
  6365. int i;
  6366. mus_float_t sum = 0.0;
  6367. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *rr, *fdbk, *gain;
  6368. x0 = bank->x0;
  6369. x1 = bank->x1;
  6370. x2 = bank->x2;
  6371. y0 = bank->y0;
  6372. y1 = bank->y1;
  6373. y2 = bank->y2;
  6374. rr = bank->rr;
  6375. fdbk = bank->fdbk;
  6376. gain = bank->gain;
  6377. amps = bank->amps;
  6378. for (i = 0; i < bank->size; i++)
  6379. {
  6380. x0[i] = gain[i] * inval[i];
  6381. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6382. sum += amps[i] * y0[i];
  6383. }
  6384. bank->x2 = x1;
  6385. bank->x1 = x0;
  6386. bank->x0 = x2;
  6387. bank->y2 = y1;
  6388. bank->y1 = y0;
  6389. bank->y0 = y2;
  6390. return(sum);
  6391. }
  6392. static mus_float_t fb_many_without_amps(mus_any *fbank, mus_float_t *inval)
  6393. {
  6394. frm_bank *bank = (frm_bank *)fbank;
  6395. int i;
  6396. mus_float_t sum = 0.0;
  6397. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *rr, *fdbk, *gain;
  6398. x0 = bank->x0;
  6399. x1 = bank->x1;
  6400. x2 = bank->x2;
  6401. y0 = bank->y0;
  6402. y1 = bank->y1;
  6403. y2 = bank->y2;
  6404. rr = bank->rr;
  6405. fdbk = bank->fdbk;
  6406. gain = bank->gain;
  6407. for (i = 0; i < bank->size; i++)
  6408. {
  6409. x0[i] = gain[i] * inval[i];
  6410. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr[i] * y2[i]);
  6411. sum += y0[i];
  6412. }
  6413. bank->x2 = x1;
  6414. bank->x1 = x0;
  6415. bank->x0 = x2;
  6416. bank->y2 = y1;
  6417. bank->y1 = y0;
  6418. bank->y0 = y2;
  6419. return(sum);
  6420. }
  6421. static mus_float_t fb_one_with_amps_c1_c2(mus_any *fbank, mus_float_t inval)
  6422. {
  6423. frm_bank *bank = (frm_bank *)fbank;
  6424. int i, size4;
  6425. mus_float_t sum = 0.0, rr, gain;
  6426. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *fdbk;
  6427. x0 = bank->x0;
  6428. x1 = bank->x1;
  6429. x2 = bank->x2;
  6430. y0 = bank->y0;
  6431. y1 = bank->y1;
  6432. y2 = bank->y2;
  6433. fdbk = bank->fdbk;
  6434. amps = bank->amps;
  6435. size4 = bank->size - 4;
  6436. bank->mctr++;
  6437. rr = bank->c1;
  6438. gain = (bank->c2 * inval);
  6439. x0[0] = gain;
  6440. if (bank->mctr < 3)
  6441. {
  6442. i = 0;
  6443. while (i <= size4)
  6444. {
  6445. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6446. sum += amps[i] * y0[i];
  6447. i++;
  6448. /* in isolation this looks like the x0[i]-x2[i] business could be handled outside the loop
  6449. * by a single float, but formant-bank can be called in the same do-loop both with and
  6450. * without multiple inputs, so fb_one has to be completely compatible sample-by-sample
  6451. * with fb_many. Since we can't predict here when we'll need bank->x2, we can't collapse
  6452. * this calculation.
  6453. *
  6454. * If we know we've had 2 fb_one calls just before this one, then x2[i] are all the same,
  6455. * x0[i] will all be the same in this loop, so x0[i] - x2[i] can be collapsed, but
  6456. * we still need to set x0[0]=gain: enter mctr.
  6457. *
  6458. * So in the current case, we can save x0[0]=gain -> x1 -> x2, then in fm_many
  6459. * mctr=1 -- x2 is ok, x1[0] needs to be propagated
  6460. * mctr>1 -- x2 and x1 need propagation
  6461. * On the other side, if mctr>=3, then x2[i] was not set, so don't access it.
  6462. */
  6463. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6464. sum += amps[i] * y0[i];
  6465. i++;
  6466. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6467. sum += amps[i] * y0[i];
  6468. i++;
  6469. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6470. sum += amps[i] * y0[i];
  6471. i++;
  6472. }
  6473. for (; i < bank->size; i++)
  6474. {
  6475. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6476. sum += amps[i] * y0[i];
  6477. }
  6478. }
  6479. else
  6480. {
  6481. mus_float_t g2;
  6482. g2 = gain - x2[0];
  6483. i = 0;
  6484. while (i <= size4)
  6485. {
  6486. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6487. sum += amps[i] * y0[i];
  6488. i++;
  6489. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6490. sum += amps[i] * y0[i];
  6491. i++;
  6492. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6493. sum += amps[i] * y0[i];
  6494. i++;
  6495. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6496. sum += amps[i] * y0[i];
  6497. i++;
  6498. }
  6499. for (; i < bank->size; i++)
  6500. {
  6501. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6502. sum += amps[i] * y0[i];
  6503. }
  6504. }
  6505. bank->x2 = x1;
  6506. bank->x1 = x0;
  6507. bank->x0 = x2;
  6508. bank->y2 = y1;
  6509. bank->y1 = y0;
  6510. bank->y0 = y2;
  6511. return(sum);
  6512. }
  6513. static mus_float_t fb_many_with_amps_c1_c2(mus_any *fbank, mus_float_t *inval)
  6514. {
  6515. frm_bank *bank = (frm_bank *)fbank;
  6516. int i, size4;
  6517. mus_float_t sum = 0.0, rr, gain;
  6518. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *amps, *fdbk;
  6519. x0 = bank->x0;
  6520. x1 = bank->x1;
  6521. x2 = bank->x2;
  6522. y0 = bank->y0;
  6523. y1 = bank->y1;
  6524. y2 = bank->y2;
  6525. fdbk = bank->fdbk;
  6526. amps = bank->amps;
  6527. size4 = bank->size - 4;
  6528. if (bank->mctr > 0)
  6529. {
  6530. if (bank->mctr == 1)
  6531. {
  6532. for (i = 1; i < bank->size; i++) x1[i] = x1[0];
  6533. }
  6534. else
  6535. {
  6536. for (i = 1; i < bank->size; i++) {x1[i] = x1[0]; x2[i] = x2[0];}
  6537. }
  6538. bank->mctr = 0;
  6539. }
  6540. rr = bank->c1;
  6541. gain = bank->c2;
  6542. i = 0;
  6543. while (i <= size4)
  6544. {
  6545. x0[i] = gain * inval[i];
  6546. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6547. sum += amps[i] * y0[i];
  6548. i++;
  6549. x0[i] = gain * inval[i];
  6550. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6551. sum += amps[i] * y0[i];
  6552. i++;
  6553. x0[i] = gain * inval[i];
  6554. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6555. sum += amps[i] * y0[i];
  6556. i++;
  6557. x0[i] = gain * inval[i];
  6558. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6559. sum += amps[i] * y0[i];
  6560. i++;
  6561. }
  6562. for (; i < bank->size; i++)
  6563. {
  6564. x0[i] = gain * inval[i];
  6565. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6566. sum += amps[i] * y0[i];
  6567. }
  6568. bank->x2 = x1;
  6569. bank->x1 = x0;
  6570. bank->x0 = x2;
  6571. bank->y2 = y1;
  6572. bank->y1 = y0;
  6573. bank->y0 = y2;
  6574. return(sum);
  6575. }
  6576. static mus_float_t fb_one_without_amps_c1_c2(mus_any *fbank, mus_float_t inval)
  6577. {
  6578. frm_bank *bank = (frm_bank *)fbank;
  6579. int i, size4;
  6580. mus_float_t sum = 0.0, rr, gain;
  6581. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *fdbk;
  6582. x0 = bank->x0;
  6583. x1 = bank->x1;
  6584. x2 = bank->x2;
  6585. y0 = bank->y0;
  6586. y1 = bank->y1;
  6587. y2 = bank->y2;
  6588. fdbk = bank->fdbk;
  6589. size4 = bank->size - 4;
  6590. bank->mctr++;
  6591. rr = bank->c1;
  6592. gain = (bank->c2 * inval);
  6593. x0[0] = gain;
  6594. if (bank->mctr < 3)
  6595. {
  6596. i = 0;
  6597. while (i <= size4)
  6598. {
  6599. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6600. sum += y0[i];
  6601. i++;
  6602. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6603. sum += y0[i];
  6604. i++;
  6605. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6606. sum += y0[i];
  6607. i++;
  6608. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6609. sum += y0[i];
  6610. i++;
  6611. }
  6612. for (; i < bank->size; i++)
  6613. {
  6614. y0[i] = gain - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6615. sum += y0[i];
  6616. }
  6617. }
  6618. else
  6619. {
  6620. mus_float_t g2;
  6621. g2 = gain - x2[0];
  6622. i = 0;
  6623. while (i <= size4)
  6624. {
  6625. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6626. sum += y0[i];
  6627. i++;
  6628. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6629. sum += y0[i];
  6630. i++;
  6631. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6632. sum += y0[i];
  6633. i++;
  6634. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6635. sum += y0[i];
  6636. i++;
  6637. }
  6638. for (; i < bank->size; i++)
  6639. {
  6640. y0[i] = g2 + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6641. sum += y0[i];
  6642. }
  6643. }
  6644. bank->x2 = x1;
  6645. bank->x1 = x0;
  6646. bank->x0 = x2;
  6647. bank->y2 = y1;
  6648. bank->y1 = y0;
  6649. bank->y0 = y2;
  6650. return(sum);
  6651. }
  6652. static mus_float_t fb_many_without_amps_c1_c2(mus_any *fbank, mus_float_t *inval)
  6653. {
  6654. frm_bank *bank = (frm_bank *)fbank;
  6655. int i, size4;
  6656. mus_float_t sum = 0.0, rr, gain;
  6657. mus_float_t *x0, *x1, *x2, *y0, *y1, *y2, *fdbk;
  6658. x0 = bank->x0;
  6659. x1 = bank->x1;
  6660. x2 = bank->x2;
  6661. y0 = bank->y0;
  6662. y1 = bank->y1;
  6663. y2 = bank->y2;
  6664. fdbk = bank->fdbk;
  6665. size4 = bank->size - 4;
  6666. if (bank->mctr > 0)
  6667. {
  6668. if (bank->mctr == 1)
  6669. {
  6670. for (i = 1; i < bank->size; i++) x1[i] = x1[0];
  6671. }
  6672. else
  6673. {
  6674. for (i = 1; i < bank->size; i++) {x1[i] = x1[0]; x2[i] = x2[0];}
  6675. }
  6676. bank->mctr = 0;
  6677. }
  6678. rr = bank->c1;
  6679. gain = bank->c2;
  6680. i = 0;
  6681. while (i <= size4)
  6682. {
  6683. x0[i] = gain * inval[i];
  6684. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6685. sum += y0[i];
  6686. i++;
  6687. x0[i] = gain * inval[i];
  6688. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6689. sum += y0[i];
  6690. i++;
  6691. x0[i] = gain * inval[i];
  6692. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6693. sum += y0[i];
  6694. i++;
  6695. x0[i] = gain * inval[i];
  6696. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6697. sum += y0[i];
  6698. i++;
  6699. }
  6700. for (; i < bank->size; i++)
  6701. {
  6702. x0[i] = gain * inval[i];
  6703. y0[i] = x0[i] - x2[i] + (fdbk[i] * y1[i]) - (rr * y2[i]);
  6704. sum += y0[i];
  6705. }
  6706. bank->x2 = x1;
  6707. bank->x1 = x0;
  6708. bank->x0 = x2;
  6709. bank->y2 = y1;
  6710. bank->y1 = y0;
  6711. bank->y0 = y2;
  6712. return(sum);
  6713. }
  6714. static mus_any_class FORMANT_BANK_CLASS = {
  6715. MUS_FORMANT_BANK,
  6716. (char *)S_formant_bank,
  6717. &free_formant_bank,
  6718. &describe_formant_bank,
  6719. &formant_bank_equalp,
  6720. 0, 0,
  6721. &formant_bank_length, 0,
  6722. 0, 0,
  6723. 0, 0,
  6724. 0, 0,
  6725. 0, 0,
  6726. &run_formant_bank,
  6727. MUS_NOT_SPECIAL,
  6728. NULL, 0,
  6729. 0, 0, 0, 0,
  6730. 0, 0,
  6731. 0, 0, 0, 0,
  6732. 0, 0, 0, 0, 0, 0, 0,
  6733. 0, 0, 0, 0,
  6734. &formant_bank_reset,
  6735. 0, &frm_bank_copy
  6736. };
  6737. mus_any *mus_make_formant_bank(int size, mus_any **formants, mus_float_t *amps)
  6738. {
  6739. frm_bank *gen;
  6740. int i;
  6741. gen = (frm_bank *)malloc(sizeof(frm_bank));
  6742. gen->core = &FORMANT_BANK_CLASS;
  6743. gen->size = size;
  6744. gen->mctr = 0;
  6745. gen->x0 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6746. gen->x1 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6747. gen->x2 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6748. gen->y0 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6749. gen->y1 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6750. gen->y2 = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  6751. gen->amps = amps;
  6752. gen->rr = (mus_float_t *)malloc(size * sizeof(mus_float_t));
  6753. gen->fdbk = (mus_float_t *)malloc(size * sizeof(mus_float_t));
  6754. gen->gain = (mus_float_t *)malloc(size * sizeof(mus_float_t));
  6755. if (amps)
  6756. {
  6757. gen->one_input = fb_one_with_amps;
  6758. gen->many_inputs = fb_many_with_amps;
  6759. }
  6760. else
  6761. {
  6762. gen->one_input = fb_one_without_amps;
  6763. gen->many_inputs = fb_many_without_amps;
  6764. }
  6765. for (i = 0; i < size; i++)
  6766. {
  6767. frm *g;
  6768. g = (frm *)formants[i];
  6769. gen->rr[i] = g->rr;
  6770. gen->fdbk[i] = g->fdbk;
  6771. gen->gain[i] = g->gain;
  6772. /* one case: 1.0 val 0.0 throughout
  6773. * also c1 x c2
  6774. */
  6775. }
  6776. gen->c1 = gen->rr[0];
  6777. gen->c2 = gen->gain[0];
  6778. for (i = 1; i < size; i++)
  6779. if ((gen->rr[i] != gen->c1) ||
  6780. (gen->gain[i] != gen->c2))
  6781. return((mus_any *)gen);
  6782. if (amps)
  6783. {
  6784. gen->one_input = fb_one_with_amps_c1_c2;
  6785. gen->many_inputs = fb_many_with_amps_c1_c2;
  6786. }
  6787. else
  6788. {
  6789. gen->one_input = fb_one_without_amps_c1_c2;
  6790. gen->many_inputs = fb_many_without_amps_c1_c2;
  6791. }
  6792. return((mus_any *)gen);
  6793. }
  6794. bool mus_is_formant_bank(mus_any *ptr)
  6795. {
  6796. return((ptr) &&
  6797. (ptr->core->type == MUS_FORMANT_BANK));
  6798. }
  6799. /* ---------------- firmant ---------------- */
  6800. static char *describe_firmant(mus_any *ptr)
  6801. {
  6802. frm *gen = (frm *)ptr;
  6803. char *describe_buffer;
  6804. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  6805. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s frequency: %.3f, radius: %.3f",
  6806. mus_name(ptr),
  6807. mus_radians_to_hz(gen->frequency),
  6808. gen->radius);
  6809. return(describe_buffer);
  6810. }
  6811. static mus_float_t firmant_frequency(mus_any *ptr) {return(mus_radians_to_hz(((frm *)ptr)->frequency));}
  6812. static mus_float_t firmant_set_frequency(mus_any *ptr, mus_float_t freq_in_hz)
  6813. {
  6814. frm *gen = (frm *)ptr;
  6815. mus_float_t fw;
  6816. fw = mus_hz_to_radians(freq_in_hz);
  6817. gen->frequency = fw;
  6818. gen->fdbk = 2.0 * sin(gen->frequency * 0.5);
  6819. return(freq_in_hz);
  6820. }
  6821. static mus_float_t firmant_radius(mus_any *ptr) {return(((frm *)ptr)->radius);}
  6822. static mus_float_t firmant_set_radius(mus_any *ptr, mus_float_t radius)
  6823. {
  6824. frm *gen = (frm *)ptr;
  6825. gen->radius = radius;
  6826. gen->gain = 1.0 - radius * radius;
  6827. return(radius);
  6828. }
  6829. bool mus_is_firmant(mus_any *ptr)
  6830. {
  6831. return((ptr) &&
  6832. (ptr->core->type == MUS_FIRMANT));
  6833. }
  6834. mus_float_t mus_firmant(mus_any *ptr, mus_float_t input)
  6835. {
  6836. frm *gen = (frm *)ptr;
  6837. mus_float_t xn1, yn1;
  6838. xn1 = gen->gain * input + gen->radius * (gen->x1 - gen->fdbk * gen->y1);
  6839. yn1 = gen->radius * (gen->fdbk * xn1 + gen->y1);
  6840. gen->x1 = xn1;
  6841. gen->y1 = yn1;
  6842. return(yn1);
  6843. }
  6844. mus_float_t mus_firmant_with_frequency(mus_any *ptr, mus_float_t input, mus_float_t freq_in_radians)
  6845. {
  6846. frm *gen = (frm *)ptr;
  6847. gen->frequency = freq_in_radians;
  6848. gen->fdbk = 2.0 * sin(gen->frequency * 0.5);
  6849. return(mus_firmant(ptr, input));
  6850. }
  6851. static mus_float_t run_firmant(mus_any *ptr, mus_float_t input, mus_float_t unused) {return(mus_firmant(ptr, input));}
  6852. static mus_any_class FIRMANT_CLASS = {
  6853. MUS_FIRMANT,
  6854. (char *)S_firmant,
  6855. &free_frm,
  6856. &describe_firmant,
  6857. &frm_equalp,
  6858. 0, 0,
  6859. &two_length, 0,
  6860. &firmant_frequency, &firmant_set_frequency,
  6861. 0, 0,
  6862. &firmant_radius, &firmant_set_radius,
  6863. 0, 0,
  6864. &run_firmant,
  6865. MUS_SIMPLE_FILTER,
  6866. NULL, 0,
  6867. 0, 0, 0, 0,
  6868. 0, 0,
  6869. 0, 0, 0, 0,
  6870. 0, 0, 0, 0, 0, 0, 0,
  6871. 0, 0, 0, 0,
  6872. &frm_reset,
  6873. 0, &frm_copy
  6874. };
  6875. mus_any *mus_make_firmant(mus_float_t frequency, mus_float_t radius)
  6876. {
  6877. frm *gen;
  6878. gen = (frm *)calloc(1, sizeof(frm));
  6879. gen->core = &FIRMANT_CLASS;
  6880. gen->frequency = mus_hz_to_radians(frequency);
  6881. gen->radius = radius;
  6882. gen->fdbk = 2.0 * sin(gen->frequency * 0.5);
  6883. gen->gain = 1.0 - radius * radius;
  6884. return((mus_any *)gen);
  6885. }
  6886. /* ---------------- filter ---------------- */
  6887. typedef struct {
  6888. mus_any_class *core;
  6889. int order, allocated_size, loc;
  6890. bool state_allocated;
  6891. mus_float_t *x, *y, *state;
  6892. mus_float_t (*filtw)(mus_any *ptr, mus_float_t fm);
  6893. } flt;
  6894. mus_float_t mus_filter(mus_any *ptr, mus_float_t input)
  6895. {
  6896. return((((flt *)ptr)->filtw)(ptr, input));
  6897. }
  6898. static mus_float_t filter_eight(mus_any *ptr, mus_float_t input)
  6899. {
  6900. /* oddly enough, this separated form is faster than the interleaved version below, or is valgrind confused?
  6901. */
  6902. flt *gen = (flt *)ptr;
  6903. mus_float_t xout;
  6904. mus_float_t *state, *ts, *ts1, *y, *x;
  6905. x = (mus_float_t *)(gen->x);
  6906. y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */
  6907. state = (mus_float_t *)(gen->state + gen->loc);
  6908. ts = (mus_float_t *)(state + gen->order - 1);
  6909. ts1 = (mus_float_t *)(state + gen->order);
  6910. gen->loc++;
  6911. if (gen->loc == gen->order)
  6912. gen->loc = 0;
  6913. input -= ((*ts--) * (*y++));
  6914. input -= ((*ts--) * (*y++));
  6915. input -= ((*ts--) * (*y++));
  6916. input -= ((*ts--) * (*y++));
  6917. input -= ((*ts--) * (*y++));
  6918. input -= ((*ts--) * (*y++));
  6919. input -= ((*ts--) * (*y++));
  6920. input -= ((*ts) * (*y));
  6921. state[0] = input;
  6922. state[gen->order] = input;
  6923. xout = (*ts1--) * (*x++);
  6924. xout += (*ts1--) * (*x++);
  6925. xout += (*ts1--) * (*x++);
  6926. xout += (*ts1--) * (*x++);
  6927. xout += (*ts1--) * (*x++);
  6928. xout += (*ts1--) * (*x++);
  6929. xout += (*ts1--) * (*x++);
  6930. xout += (*ts1--) * (*x++);
  6931. return(xout + ((*ts1) * (*x)));
  6932. /*
  6933. * flt *gen = (flt *)ptr;
  6934. * mus_float_t xout;
  6935. * mus_float_t *state, *ts, *y, *x;
  6936. *
  6937. * x = (mus_float_t *)(gen->x + 1);
  6938. * y = (mus_float_t *)(gen->y + 1);
  6939. * state = (mus_float_t *)(gen->state + gen->loc);
  6940. * ts = (mus_float_t *)(state + gen->order - 1);
  6941. *
  6942. * gen->loc++;
  6943. * if (gen->loc == gen->order)
  6944. * gen->loc = 0;
  6945. *
  6946. * xout = (*ts) * (*x++);
  6947. * input -= ((*ts--) * (*y++));
  6948. * xout += (*ts) * (*x++);
  6949. * input -= ((*ts--) * (*y++));
  6950. * xout += (*ts) * (*x++);
  6951. * input -= ((*ts--) * (*y++));
  6952. * xout += (*ts) * (*x++);
  6953. * input -= ((*ts--) * (*y++));
  6954. * xout += (*ts) * (*x++);
  6955. * input -= ((*ts--) * (*y++));
  6956. * xout += (*ts) * (*x++);
  6957. * input -= ((*ts--) * (*y++));
  6958. * xout += (*ts) * (*x++);
  6959. * input -= ((*ts--) * (*y++));
  6960. * xout += (*ts) * (*x);
  6961. * input -= ((*ts--) * (*y));
  6962. *
  6963. * state[0] = input;
  6964. * state[gen->order] = input;
  6965. * return(xout + ((*ts) * gen->x[0]));
  6966. */
  6967. }
  6968. static mus_float_t filter_four(mus_any *ptr, mus_float_t input)
  6969. {
  6970. flt *gen = (flt *)ptr;
  6971. mus_float_t xout;
  6972. mus_float_t *state, *ts, *ts1, *y, *x;
  6973. x = (mus_float_t *)(gen->x);
  6974. y = (mus_float_t *)(gen->y + 1);
  6975. state = (mus_float_t *)(gen->state + gen->loc);
  6976. ts = (mus_float_t *)(state + gen->order - 1);
  6977. ts1 = (mus_float_t *)(state + gen->order);
  6978. gen->loc++;
  6979. if (gen->loc == gen->order)
  6980. gen->loc = 0;
  6981. input -= ((*ts--) * (*y++));
  6982. input -= ((*ts--) * (*y++));
  6983. input -= ((*ts--) * (*y++));
  6984. input -= ((*ts) * (*y));
  6985. state[0] = input;
  6986. state[gen->order] = input;
  6987. xout = (*ts1--) * (*x++);
  6988. xout += (*ts1--) * (*x++);
  6989. xout += (*ts1--) * (*x++);
  6990. xout += (*ts1--) * (*x++);
  6991. return(xout + ((*ts1) * (*x)));
  6992. /*
  6993. * flt *gen = (flt *)ptr;
  6994. * mus_float_t xout;
  6995. * mus_float_t *state, *ts, *y, *x;
  6996. *
  6997. * x = (mus_float_t *)(gen->x + 1);
  6998. * y = (mus_float_t *)(gen->y + 1);
  6999. * state = (mus_float_t *)(gen->state + gen->loc);
  7000. * ts = (mus_float_t *)(state + gen->order - 1);
  7001. *
  7002. * gen->loc++;
  7003. * if (gen->loc == gen->order)
  7004. * gen->loc = 0;
  7005. *
  7006. * xout = (*ts) * (*x++);
  7007. * input -= ((*ts--) * (*y++));
  7008. * xout += (*ts) * (*x++);
  7009. * input -= ((*ts--) * (*y++));
  7010. * xout += (*ts) * (*x++);
  7011. * input -= ((*ts--) * (*y++));
  7012. * xout += (*ts) * (*x++);
  7013. * input -= ((*ts--) * (*y++));
  7014. *
  7015. * state[0] = input;
  7016. * state[gen->order] = input;
  7017. * return(xout + ((*ts) * gen->x[0]));
  7018. */
  7019. }
  7020. static mus_float_t filter_two(mus_any *ptr, mus_float_t input)
  7021. {
  7022. /* here the mus_float_t-delay form is not faster, but use it for consistency */
  7023. flt *gen = (flt *)ptr;
  7024. mus_float_t *state, *ts, *y, *x;
  7025. x = gen->x;
  7026. y = gen->y;
  7027. state = (mus_float_t *)(gen->state + gen->loc);
  7028. ts = (mus_float_t *)(state + gen->order - 2);
  7029. gen->loc++;
  7030. if (gen->loc == gen->order)
  7031. gen->loc = 0;
  7032. state[0] = input - ((ts[1] * y[1]) + (ts[0] * y[2]));
  7033. state[gen->order] = state[0];
  7034. return((ts[0] * x[2]) + (ts[1] * x[1]) + (ts[2] * x[0]));
  7035. }
  7036. static mus_float_t filter_lt_10(mus_any *ptr, mus_float_t input)
  7037. {
  7038. flt *gen = (flt *)ptr;
  7039. mus_float_t xout = 0.0;
  7040. mus_float_t *state, *state1, *ts, *y, *x;
  7041. x = (mus_float_t *)(gen->x);
  7042. y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */
  7043. state = (mus_float_t *)(gen->state + gen->loc);
  7044. state1 = (mus_float_t *)(state + 1);
  7045. ts = (mus_float_t *)(state + gen->order - 1);
  7046. while (ts > state1)
  7047. input -= ((*ts--) * (*y++));
  7048. input -= ((*ts) * (*y));
  7049. state[0] = input;
  7050. state[gen->order] = input;
  7051. ts = (mus_float_t *)(state + gen->order);
  7052. while (ts > state1)
  7053. xout += (*ts--) * (*x++);
  7054. gen->loc++;
  7055. if (gen->loc == gen->order)
  7056. gen->loc = 0;
  7057. return(xout + ((*ts) * (*x)));
  7058. }
  7059. static mus_float_t filter_ge_10(mus_any *ptr, mus_float_t input)
  7060. {
  7061. flt *gen = (flt *)ptr;
  7062. mus_float_t xout = 0.0;
  7063. mus_float_t *state, *state1, *state11, *ts, *y, *x;
  7064. x = (mus_float_t *)(gen->x);
  7065. y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */
  7066. state = (mus_float_t *)(gen->state + gen->loc);
  7067. state1 = (mus_float_t *)(state + 1);
  7068. state11 = (mus_float_t *)(state + 11);
  7069. ts = (mus_float_t *)(state + gen->order - 1);
  7070. while (ts >= state11)
  7071. {
  7072. input -= ((*ts--) * (*y++));
  7073. input -= ((*ts--) * (*y++));
  7074. input -= ((*ts--) * (*y++));
  7075. input -= ((*ts--) * (*y++));
  7076. input -= ((*ts--) * (*y++));
  7077. input -= ((*ts--) * (*y++));
  7078. input -= ((*ts--) * (*y++));
  7079. input -= ((*ts--) * (*y++));
  7080. input -= ((*ts--) * (*y++));
  7081. input -= ((*ts--) * (*y++));
  7082. }
  7083. while (ts > state1)
  7084. input -= ((*ts--) * (*y++));
  7085. input -= ((*ts) * (*y));
  7086. state[0] = input;
  7087. state[gen->order] = input;
  7088. ts = (mus_float_t *)(state + gen->order);
  7089. while (ts >= state11)
  7090. {
  7091. xout += (*ts--) * (*x++);
  7092. xout += (*ts--) * (*x++);
  7093. xout += (*ts--) * (*x++);
  7094. xout += (*ts--) * (*x++);
  7095. xout += (*ts--) * (*x++);
  7096. xout += (*ts--) * (*x++);
  7097. xout += (*ts--) * (*x++);
  7098. xout += (*ts--) * (*x++);
  7099. xout += (*ts--) * (*x++);
  7100. xout += (*ts--) * (*x++);
  7101. }
  7102. while (ts > state1)
  7103. xout += (*ts--) * (*x++);
  7104. gen->loc++;
  7105. if (gen->loc == gen->order)
  7106. gen->loc = 0;
  7107. return(xout + ((*ts) * (*x)));
  7108. }
  7109. mus_float_t mus_fir_filter(mus_any *ptr, mus_float_t input)
  7110. {
  7111. return((((flt *)ptr)->filtw)(ptr, input));
  7112. }
  7113. static mus_float_t fir_n(mus_any *ptr, mus_float_t input)
  7114. {
  7115. mus_float_t xout = 0.0;
  7116. flt *gen = (flt *)ptr;
  7117. mus_float_t *state, *ts, *x, *end;
  7118. x = (mus_float_t *)(gen->x);
  7119. state = (mus_float_t *)(gen->state + gen->loc);
  7120. ts = (mus_float_t *)(state + gen->order);
  7121. (*state) = input;
  7122. (*ts) = input;
  7123. state++;
  7124. end = (mus_float_t *)(state + 4);
  7125. while (ts > end)
  7126. {
  7127. xout += (*ts--) * (*x++);
  7128. xout += (*ts--) * (*x++);
  7129. xout += (*ts--) * (*x++);
  7130. xout += (*ts--) * (*x++);
  7131. }
  7132. while (ts > state)
  7133. xout += (*ts--) * (*x++);
  7134. gen->loc++;
  7135. if (gen->loc == gen->order)
  7136. gen->loc = 0;
  7137. return(xout + ((*ts) * (*x)));
  7138. }
  7139. static mus_float_t fir_ge_20(mus_any *ptr, mus_float_t input)
  7140. {
  7141. mus_float_t xout = 0.0;
  7142. flt *gen = (flt *)ptr;
  7143. mus_float_t *state, *ts, *x, *end;
  7144. x = (mus_float_t *)(gen->x);
  7145. state = (mus_float_t *)(gen->state + gen->loc);
  7146. ts = (mus_float_t *)(state + gen->order);
  7147. end = (mus_float_t *)(state + 20);
  7148. (*state) = input;
  7149. (*ts) = input;
  7150. state++;
  7151. while (ts >= end)
  7152. {
  7153. xout += (*ts--) * (*x++);
  7154. xout += (*ts--) * (*x++);
  7155. xout += (*ts--) * (*x++);
  7156. xout += (*ts--) * (*x++);
  7157. xout += (*ts--) * (*x++);
  7158. xout += (*ts--) * (*x++);
  7159. xout += (*ts--) * (*x++);
  7160. xout += (*ts--) * (*x++);
  7161. xout += (*ts--) * (*x++);
  7162. xout += (*ts--) * (*x++);
  7163. xout += (*ts--) * (*x++);
  7164. xout += (*ts--) * (*x++);
  7165. xout += (*ts--) * (*x++);
  7166. xout += (*ts--) * (*x++);
  7167. xout += (*ts--) * (*x++);
  7168. xout += (*ts--) * (*x++);
  7169. xout += (*ts--) * (*x++);
  7170. xout += (*ts--) * (*x++);
  7171. xout += (*ts--) * (*x++);
  7172. xout += (*ts--) * (*x++);
  7173. }
  7174. while (ts > state)
  7175. xout += (*ts--) * (*x++);
  7176. gen->loc++;
  7177. if (gen->loc == gen->order)
  7178. gen->loc = 0;
  7179. return((ts == state) ? (xout + ((*ts) * (*x))) : xout);
  7180. }
  7181. mus_float_t mus_iir_filter(mus_any *ptr, mus_float_t input)
  7182. {
  7183. return((((flt *)ptr)->filtw)(ptr, input));
  7184. }
  7185. static mus_float_t iir_n(mus_any *ptr, mus_float_t input)
  7186. {
  7187. flt *gen = (flt *)ptr;
  7188. mus_float_t *state, *ts, *y;
  7189. y = (mus_float_t *)(gen->y + 1); /* assume y[0] = 1.0 I think */
  7190. state = (mus_float_t *)(gen->state + gen->loc);
  7191. ts = (mus_float_t *)(state + gen->order - 1);
  7192. while (ts > state)
  7193. input -= ((*ts--) * (*y++));
  7194. gen->loc++;
  7195. if (gen->loc == gen->order)
  7196. gen->loc = 0;
  7197. state[0] = input;
  7198. state[gen->order] = input;
  7199. return(input);
  7200. }
  7201. static mus_float_t run_filter(mus_any *ptr, mus_float_t input, mus_float_t unused) {return((((flt *)ptr)->filtw)(ptr, input));}
  7202. bool mus_is_filter(mus_any *ptr)
  7203. {
  7204. return((ptr) &&
  7205. ((ptr->core->type == MUS_FILTER) ||
  7206. (ptr->core->type == MUS_FIR_FILTER) ||
  7207. (ptr->core->type == MUS_IIR_FILTER)));
  7208. }
  7209. bool mus_is_fir_filter(mus_any *ptr)
  7210. {
  7211. return((ptr) &&
  7212. (ptr->core->type == MUS_FIR_FILTER));
  7213. }
  7214. bool mus_is_iir_filter(mus_any *ptr)
  7215. {
  7216. return((ptr) &&
  7217. (ptr->core->type == MUS_IIR_FILTER));
  7218. }
  7219. static mus_float_t *filter_data(mus_any *ptr) {return(((flt *)ptr)->state);}
  7220. static mus_long_t filter_length(mus_any *ptr) {return(((flt *)ptr)->order);}
  7221. static mus_float_t *filter_xcoeffs(mus_any *ptr) {return(((flt *)ptr)->x);}
  7222. static mus_float_t *filter_ycoeffs(mus_any *ptr) {return(((flt *)ptr)->y);}
  7223. mus_float_t *mus_filter_set_xcoeffs(mus_any *ptr, mus_float_t *new_data)
  7224. {
  7225. /* needed by Snd if filter order increased during play */
  7226. flt *gen = (flt *)ptr;
  7227. mus_float_t *old_data;
  7228. old_data = gen->x;
  7229. gen->x = new_data;
  7230. return(old_data);
  7231. }
  7232. mus_float_t *mus_filter_set_ycoeffs(mus_any *ptr, mus_float_t *new_data)
  7233. {
  7234. flt *gen = (flt *)ptr;
  7235. mus_float_t *old_data;
  7236. old_data = gen->y;
  7237. gen->y = new_data;
  7238. return(old_data);
  7239. }
  7240. static mus_long_t filter_set_length(mus_any *ptr, mus_long_t val)
  7241. {
  7242. /* just resets order if order < allocated size */
  7243. flt *gen = (flt *)ptr;
  7244. if ((val > 0) && (val <= gen->allocated_size))
  7245. gen->order = (int)val;
  7246. return((mus_long_t)(gen->order));
  7247. }
  7248. static void set_filter_function(flt *gen);
  7249. int mus_filter_set_order(mus_any *ptr, int order)
  7250. {
  7251. /* resets order and fixes state array if needed (coeffs arrays should be handled separately by set_x|ycoeffs above) */
  7252. /* returns either old order or -1 if state array can't be reallocated */
  7253. flt *gen = (flt *)ptr;
  7254. int old_order;
  7255. if ((order > gen->allocated_size) &&
  7256. (!(gen->state_allocated)))
  7257. return(-1);
  7258. old_order = gen->order;
  7259. gen->order = order;
  7260. if (order > gen->allocated_size)
  7261. {
  7262. int i;
  7263. gen->allocated_size = order;
  7264. gen->state = (mus_float_t *)realloc(gen->state, order * 2 * sizeof(mus_float_t));
  7265. for (i = old_order; i < order; i++)
  7266. {
  7267. gen->state[i] = 0.0; /* try to minimize click */
  7268. gen->state[i + order] = 0.0; /* just a guess */
  7269. }
  7270. }
  7271. set_filter_function(gen);
  7272. return(old_order);
  7273. }
  7274. static mus_float_t filter_xcoeff(mus_any *ptr, int index)
  7275. {
  7276. flt *gen = (flt *)ptr;
  7277. if (!(gen->x)) return((mus_float_t)mus_error(MUS_NO_XCOEFFS, S_mus_xcoeff ": no xcoeffs"));
  7278. if ((index >= 0) && (index < gen->order))
  7279. return(gen->x[index]);
  7280. return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_mus_xcoeff ": invalid index %d, order = %d?", index, gen->order));
  7281. }
  7282. static mus_float_t filter_set_xcoeff(mus_any *ptr, int index, mus_float_t val)
  7283. {
  7284. flt *gen = (flt *)ptr;
  7285. if (!(gen->x)) return((mus_float_t)mus_error(MUS_NO_XCOEFFS, S_set S_mus_xcoeff ": no xcoeffs"));
  7286. if ((index >= 0) && (index < gen->order))
  7287. {
  7288. gen->x[index] = val;
  7289. return(val);
  7290. }
  7291. return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_set S_mus_xcoeff ": invalid index %d, order = %d?", index, gen->order));
  7292. }
  7293. static mus_float_t filter_ycoeff(mus_any *ptr, int index)
  7294. {
  7295. flt *gen = (flt *)ptr;
  7296. if (!(gen->y)) return((mus_float_t)mus_error(MUS_NO_YCOEFFS, S_mus_ycoeff ": no ycoeffs"));
  7297. if ((index >= 0) && (index < gen->order))
  7298. return(gen->y[index]);
  7299. return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_mus_ycoeff ": invalid index %d, order = %d?", index, gen->order));
  7300. }
  7301. static mus_float_t filter_set_ycoeff(mus_any *ptr, int index, mus_float_t val)
  7302. {
  7303. flt *gen = (flt *)ptr;
  7304. if (!(gen->y)) return((mus_float_t)mus_error(MUS_NO_YCOEFFS, S_set S_mus_ycoeff ": no ycoeffs"));
  7305. if ((index >= 0) && (index < gen->order))
  7306. {
  7307. gen->y[index] = val;
  7308. return(val);
  7309. }
  7310. return((mus_float_t)mus_error(MUS_ARG_OUT_OF_RANGE, S_set S_mus_ycoeff ": invalid index %d, order = %d?", index, gen->order));
  7311. }
  7312. static void free_filter(mus_any *ptr)
  7313. {
  7314. flt *gen = (flt *)ptr;
  7315. if ((gen->state) && (gen->state_allocated)) free(gen->state);
  7316. free(gen);
  7317. }
  7318. static mus_any *flt_copy(mus_any *ptr)
  7319. {
  7320. flt *g, *p;
  7321. int bytes;
  7322. p = (flt *)ptr;
  7323. g = (flt *)malloc(sizeof(flt));
  7324. memcpy((void *)g, (void *)ptr, sizeof(flt));
  7325. /* we have to make a new state array -- otherwise the original and copy step on each other */
  7326. bytes = p->order * 2 * sizeof(mus_float_t);
  7327. g->state_allocated = true;
  7328. g->state = (mus_float_t *)malloc(bytes);
  7329. memcpy((void *)(g->state), (void *)(p->state), bytes);
  7330. return((mus_any *)g);
  7331. }
  7332. static bool filter_equalp(mus_any *p1, mus_any *p2)
  7333. {
  7334. flt *f1, *f2;
  7335. f1 = (flt *)p1;
  7336. f2 = (flt *)p2;
  7337. if (p1 == p2) return(true);
  7338. return(((p1->core)->type == (p2->core)->type) &&
  7339. ((mus_is_filter(p1)) || (mus_is_fir_filter(p1)) || (mus_is_iir_filter(p1))) &&
  7340. (f1->order == f2->order) &&
  7341. ((!(f1->x)) || (!(f2->x)) || (clm_arrays_are_equal(f1->x, f2->x, f1->order))) &&
  7342. ((!(f1->y)) || (!(f2->y)) || (clm_arrays_are_equal(f1->y, f2->y, f1->order))) &&
  7343. (clm_arrays_are_equal(f1->state, f2->state, f1->order)));
  7344. }
  7345. static char *describe_filter(mus_any *ptr)
  7346. {
  7347. flt *gen = (flt *)ptr;
  7348. char *xstr = NULL, *ystr = NULL;
  7349. char *describe_buffer;
  7350. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  7351. xstr = float_array_to_string(gen->x, gen->order, 0);
  7352. ystr = float_array_to_string(gen->y, gen->order, 0);
  7353. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, xs: %s, ys: %s",
  7354. mus_name(ptr),
  7355. gen->order,
  7356. xstr, ystr);
  7357. if (xstr) free(xstr);
  7358. if (ystr) free(ystr);
  7359. return(describe_buffer);
  7360. }
  7361. static char *describe_fir_filter(mus_any *ptr)
  7362. {
  7363. flt *gen = (flt *)ptr;
  7364. char *xstr = NULL;
  7365. char *describe_buffer;
  7366. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  7367. xstr = float_array_to_string(gen->x, gen->order, 0);
  7368. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, xs: %s",
  7369. mus_name(ptr),
  7370. gen->order,
  7371. xstr);
  7372. if (xstr) free(xstr);
  7373. return(describe_buffer);
  7374. }
  7375. static char *describe_iir_filter(mus_any *ptr)
  7376. {
  7377. flt *gen = (flt *)ptr;
  7378. char *ystr = NULL;
  7379. char *describe_buffer;
  7380. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  7381. ystr = float_array_to_string(gen->y, gen->order, 0);
  7382. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s order: %d, ys: %s",
  7383. mus_name(ptr),
  7384. gen->order,
  7385. ystr);
  7386. if (ystr) free(ystr);
  7387. return(describe_buffer);
  7388. }
  7389. static void filter_reset(mus_any *ptr)
  7390. {
  7391. flt *gen = (flt *)ptr;
  7392. memset((void *)(gen->state), 0, gen->allocated_size * 2 * sizeof(mus_float_t));
  7393. }
  7394. static mus_any_class FILTER_CLASS = {
  7395. MUS_FILTER,
  7396. (char *)S_filter,
  7397. &free_filter,
  7398. &describe_filter,
  7399. &filter_equalp,
  7400. &filter_data, 0,
  7401. &filter_length,
  7402. &filter_set_length,
  7403. 0, 0, 0, 0,
  7404. 0, 0,
  7405. 0, 0,
  7406. &run_filter,
  7407. MUS_FULL_FILTER,
  7408. NULL, 0,
  7409. 0, 0, 0, 0,
  7410. &filter_xcoeff, &filter_set_xcoeff,
  7411. 0, 0, 0, 0,
  7412. 0, 0, 0, 0, 0, 0, 0,
  7413. &filter_ycoeff, &filter_set_ycoeff,
  7414. &filter_xcoeffs, &filter_ycoeffs,
  7415. &filter_reset,
  7416. 0, &flt_copy
  7417. };
  7418. static mus_any_class FIR_FILTER_CLASS = {
  7419. MUS_FIR_FILTER,
  7420. (char *)S_fir_filter,
  7421. &free_filter,
  7422. &describe_fir_filter,
  7423. &filter_equalp,
  7424. &filter_data, 0,
  7425. &filter_length,
  7426. &filter_set_length,
  7427. 0, 0, 0, 0,
  7428. 0, 0,
  7429. 0, 0,
  7430. &run_filter,
  7431. MUS_FULL_FILTER,
  7432. NULL, 0,
  7433. 0, 0, 0, 0,
  7434. &filter_xcoeff, &filter_set_xcoeff,
  7435. 0, 0, 0, 0,
  7436. 0, 0, 0, 0, 0, 0, 0,
  7437. 0, 0,
  7438. &filter_xcoeffs, 0,
  7439. &filter_reset,
  7440. 0, &flt_copy
  7441. };
  7442. static mus_any_class IIR_FILTER_CLASS = {
  7443. MUS_IIR_FILTER,
  7444. (char *)S_iir_filter,
  7445. &free_filter,
  7446. &describe_iir_filter,
  7447. &filter_equalp,
  7448. &filter_data, 0,
  7449. &filter_length,
  7450. &filter_set_length,
  7451. 0, 0, 0, 0,
  7452. 0, 0,
  7453. 0, 0,
  7454. &run_filter,
  7455. MUS_FULL_FILTER,
  7456. NULL, 0,
  7457. 0, 0, 0, 0,
  7458. 0, 0,
  7459. 0, 0, 0, 0,
  7460. 0, 0, 0, 0, 0, 0, 0,
  7461. &filter_ycoeff, &filter_set_ycoeff,
  7462. 0, &filter_ycoeffs,
  7463. &filter_reset,
  7464. 0, &flt_copy
  7465. };
  7466. static void set_filter_function(flt *gen)
  7467. {
  7468. /* choose the run-time function based on the current filter order and type */
  7469. int order;
  7470. order = gen->order - 1;
  7471. if (gen->core == &FILTER_CLASS)
  7472. {
  7473. if (order == 2)
  7474. gen->filtw = filter_two;
  7475. else
  7476. {
  7477. if (order == 8)
  7478. gen->filtw = filter_eight;
  7479. else
  7480. {
  7481. if (order == 4)
  7482. gen->filtw = filter_four;
  7483. else
  7484. {
  7485. if (order >= 10)
  7486. gen->filtw = filter_ge_10;
  7487. else gen->filtw = filter_lt_10;
  7488. }
  7489. }
  7490. }
  7491. }
  7492. else
  7493. {
  7494. if (gen->core == &FIR_FILTER_CLASS)
  7495. {
  7496. if (order >= 20)
  7497. gen->filtw = fir_ge_20;
  7498. else gen->filtw = fir_n;
  7499. }
  7500. else gen->filtw = iir_n;
  7501. }
  7502. }
  7503. static mus_any *make_filter(mus_any_class *cls, const char *name, int order, mus_float_t *xcoeffs, mus_float_t *ycoeffs, mus_float_t *state)
  7504. {
  7505. /* if state is null, it is allocated locally, otherwise it's size should be at least 2 * order.
  7506. */
  7507. if (order <= 0)
  7508. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_filter ": %s order = %d?", name, order);
  7509. else
  7510. {
  7511. flt *gen;
  7512. gen = (flt *)malloc(sizeof(flt));
  7513. if (state)
  7514. {
  7515. gen->state = state;
  7516. gen->state_allocated = false;
  7517. }
  7518. else
  7519. {
  7520. gen->state = (mus_float_t *)calloc(order * 2, sizeof(mus_float_t));
  7521. gen->state_allocated = true;
  7522. }
  7523. gen->loc = 0;
  7524. if (cls == &FILTER_CLASS)
  7525. {
  7526. if (!ycoeffs)
  7527. cls = &FIR_FILTER_CLASS;
  7528. else
  7529. {
  7530. if (!xcoeffs)
  7531. cls = &IIR_FILTER_CLASS;
  7532. }
  7533. }
  7534. gen->core = cls;
  7535. gen->order = order;
  7536. gen->allocated_size = order;
  7537. gen->x = xcoeffs;
  7538. gen->y = ycoeffs;
  7539. gen->filtw = NULL;
  7540. set_filter_function(gen);
  7541. return((mus_any *)gen);
  7542. }
  7543. return(NULL);
  7544. }
  7545. mus_any *mus_make_filter(int order, mus_float_t *xcoeffs, mus_float_t *ycoeffs, mus_float_t *state)
  7546. {
  7547. return(make_filter(&FILTER_CLASS, S_make_filter, order, xcoeffs, ycoeffs, state));
  7548. }
  7549. mus_any *mus_make_fir_filter(int order, mus_float_t *xcoeffs, mus_float_t *state)
  7550. {
  7551. return(make_filter(&FIR_FILTER_CLASS, S_make_fir_filter, order, xcoeffs, NULL, state));
  7552. }
  7553. mus_any *mus_make_iir_filter(int order, mus_float_t *ycoeffs, mus_float_t *state)
  7554. {
  7555. return(make_filter(&IIR_FILTER_CLASS, S_make_iir_filter, order, NULL, ycoeffs, state));
  7556. }
  7557. mus_float_t *mus_make_fir_coeffs(int order, mus_float_t *envl, mus_float_t *aa)
  7558. {
  7559. /* envl = evenly sampled freq response, has order samples */
  7560. int n, i, j, jj;
  7561. mus_float_t scl;
  7562. mus_float_t *a;
  7563. n = order;
  7564. if (n <= 0) return(aa);
  7565. if (aa)
  7566. a = aa;
  7567. else a = (mus_float_t *)calloc(order + 1, sizeof(mus_float_t));
  7568. if (!a) return(NULL);
  7569. if (!(is_power_of_2(order)))
  7570. {
  7571. int m;
  7572. mus_float_t am, q, xt0, x;
  7573. m = (n + 1) / 2;
  7574. am = 0.5 * (n + 1) - 1.0;
  7575. scl = 2.0 / (mus_float_t)n;
  7576. q = TWO_PI / (mus_float_t)n;
  7577. xt0 = envl[0] * 0.5;
  7578. for (j = 0, jj = n - 1; j < m; j++, jj--)
  7579. {
  7580. mus_float_t xt, qj;
  7581. #if HAVE_SINCOS
  7582. double s1, c1, s2, c2, qj1;
  7583. xt = xt0;
  7584. qj = q * (am - j);
  7585. sincos(qj, &s1, &c1);
  7586. qj1 = qj * 2.0;
  7587. for (i = 1, x = qj; i < m; i += 2, x += qj1)
  7588. {
  7589. sincos(x, &s2, &c2);
  7590. xt += (envl[i] * c2);
  7591. if (i < (m - 1))
  7592. xt += (envl[i + 1] * (c1 * c2 - s1 * s2));
  7593. }
  7594. #else
  7595. xt = xt0;
  7596. qj = q * (am - j);
  7597. for (i = 1, x = qj; i < m; i++, x += qj)
  7598. xt += (envl[i] * cos(x));
  7599. #endif
  7600. a[j] = xt * scl;
  7601. a[jj] = a[j];
  7602. }
  7603. }
  7604. else /* use fft if it's easy to match -- there must be a way to handle non-power-of-2 orders here
  7605. * stretch envl to a power of 2, fft, subsample?
  7606. */
  7607. {
  7608. mus_float_t *rl, *im;
  7609. mus_long_t fsize;
  7610. int lim;
  7611. mus_float_t offset;
  7612. fsize = 2 * order; /* checked power of 2 above */
  7613. rl = (mus_float_t *)calloc(fsize, sizeof(mus_float_t));
  7614. im = (mus_float_t *)calloc(fsize, sizeof(mus_float_t));
  7615. lim = order / 2;
  7616. memcpy((void *)rl, (void *)envl, lim * sizeof(mus_float_t));
  7617. mus_fft(rl, im, fsize, 1);
  7618. scl = 4.0 / fsize;
  7619. offset = -2.0 * envl[0] / fsize;
  7620. for (i = 0; i < fsize; i++)
  7621. rl[i] = rl[i] * scl + offset;
  7622. for (i = 1, j = lim - 1, jj = lim; i < order; i += 2, j--, jj++)
  7623. {
  7624. a[j] = rl[i];
  7625. a[jj] = rl[i];
  7626. }
  7627. free(rl);
  7628. free(im);
  7629. }
  7630. return(a);
  7631. }
  7632. /* ---------------- one-pole-all-pass ---------------- */
  7633. typedef struct {
  7634. mus_any_class *core;
  7635. int size;
  7636. mus_float_t coeff;
  7637. mus_float_t *x, *y;
  7638. mus_float_t (*f)(mus_any *ptr, mus_float_t input);
  7639. } onepall;
  7640. static void free_onepall(mus_any *ptr)
  7641. {
  7642. onepall *f = (onepall *)ptr;
  7643. if (f->x) {free(f->x); f->x = NULL;}
  7644. if (f->y) {free(f->y); f->y = NULL;}
  7645. free(ptr);
  7646. }
  7647. static mus_any *onepall_copy(mus_any *ptr)
  7648. {
  7649. onepall *g, *p;
  7650. int bytes;
  7651. p = (onepall *)ptr;
  7652. g = (onepall *)malloc(sizeof(onepall));
  7653. memcpy((void *)g, (void *)ptr, sizeof(onepall));
  7654. bytes = g->size * sizeof(mus_float_t);
  7655. g->x = (mus_float_t *)malloc(bytes);
  7656. memcpy((void *)(g->x), (void *)(p->x), bytes);
  7657. g->y = (mus_float_t *)malloc(bytes);
  7658. memcpy((void *)(g->y), (void *)(p->y), bytes);
  7659. return((mus_any *)g);
  7660. }
  7661. static mus_float_t run_onepall(mus_any *ptr, mus_float_t input, mus_float_t unused)
  7662. {
  7663. return((((onepall *)ptr)->f)(ptr, input));
  7664. }
  7665. static mus_long_t onepall_length(mus_any *ptr)
  7666. {
  7667. return(((onepall *)ptr)->size);
  7668. }
  7669. static void onepall_reset(mus_any *ptr)
  7670. {
  7671. onepall *f = (onepall *)ptr;
  7672. int size;
  7673. size = f->size;
  7674. memset((void *)(f->x), 0, size * sizeof(mus_float_t));
  7675. memset((void *)(f->y), 0, size * sizeof(mus_float_t));
  7676. }
  7677. static bool onepall_equalp(mus_any *p1, mus_any *p2)
  7678. {
  7679. onepall *f1 = (onepall *)p1;
  7680. onepall *f2 = (onepall *)p2;
  7681. if (f1 == f2) return(true);
  7682. if (f1->size != f2->size) return(false);
  7683. if (f1->coeff != f2->coeff) return(false);
  7684. return((mus_arrays_are_equal(f1->x, f2->x, float_equal_fudge_factor, f1->size)) &&
  7685. (mus_arrays_are_equal(f1->y, f2->y, float_equal_fudge_factor, f1->size)));
  7686. }
  7687. static char *describe_onepall(mus_any *ptr)
  7688. {
  7689. onepall *gen = (onepall *)ptr;
  7690. char *describe_buffer;
  7691. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  7692. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %d, coeff: %f",
  7693. mus_name(ptr),
  7694. gen->size,
  7695. gen->coeff);
  7696. return(describe_buffer);
  7697. }
  7698. mus_float_t mus_one_pole_all_pass(mus_any *ptr, mus_float_t input)
  7699. {
  7700. return((((onepall *)ptr)->f)(ptr, input));
  7701. }
  7702. static mus_float_t one_pole_all_pass_n(mus_any *f, mus_float_t input)
  7703. {
  7704. onepall *p = (onepall *)f;
  7705. int i;
  7706. mus_float_t coeff, y0;
  7707. mus_float_t *x, *y;
  7708. x = p->x;
  7709. y = p->y;
  7710. coeff = p->coeff;
  7711. y0 = input;
  7712. for (i = 0; i < p->size; i++)
  7713. {
  7714. y[i] = x[i] + (coeff * (y0 - y[i]));
  7715. x[i] = y0;
  7716. y0 = y[i];
  7717. }
  7718. return(y0);
  7719. }
  7720. static mus_float_t one_pole_all_pass_8(mus_any *f, mus_float_t input)
  7721. {
  7722. onepall *p = (onepall *)f;
  7723. mus_float_t coeff;
  7724. mus_float_t *x, *y;
  7725. x = p->x;
  7726. y = p->y;
  7727. coeff = p->coeff;
  7728. y[0] = x[0] + (coeff * (input - y[0])); x[0] = input;
  7729. y[1] = x[1] + (coeff * (y[0] - y[1])); x[1] = y[0];
  7730. y[2] = x[2] + (coeff * (y[1] - y[2])); x[2] = y[1];
  7731. y[3] = x[3] + (coeff * (y[2] - y[3])); x[3] = y[2];
  7732. y[4] = x[4] + (coeff * (y[3] - y[4])); x[4] = y[3];
  7733. y[5] = x[5] + (coeff * (y[4] - y[5])); x[5] = y[4];
  7734. y[6] = x[6] + (coeff * (y[5] - y[6])); x[6] = y[5];
  7735. y[7] = x[7] + (coeff * (y[6] - y[7])); x[7] = y[6];
  7736. return(y[7]);
  7737. }
  7738. static mus_float_t one_pole_all_pass_1(mus_any *f, mus_float_t input)
  7739. {
  7740. onepall *p = (onepall *)f;
  7741. p->y[0] = p->x[0] + (p->coeff * (input - p->y[0]));
  7742. p->x[0] = input;
  7743. return(p->y[0]);
  7744. }
  7745. static mus_any_class ONE_POLE_ALL_PASS_CLASS = {
  7746. MUS_ONE_POLE_ALL_PASS,
  7747. (char *)S_one_pole_all_pass,
  7748. &free_onepall,
  7749. &describe_onepall,
  7750. &onepall_equalp,
  7751. 0, 0,
  7752. &onepall_length, 0,
  7753. 0, 0,
  7754. 0, 0,
  7755. 0, 0,
  7756. 0, 0,
  7757. &run_onepall,
  7758. MUS_NOT_SPECIAL,
  7759. NULL, 0,
  7760. 0, 0, 0, 0,
  7761. 0, 0,
  7762. 0, 0, 0, 0,
  7763. 0, 0, 0, 0, 0, 0, 0,
  7764. 0, 0, 0, 0,
  7765. &onepall_reset,
  7766. 0, &onepall_copy
  7767. };
  7768. mus_any *mus_make_one_pole_all_pass(int size, mus_float_t coeff)
  7769. {
  7770. onepall *gen;
  7771. gen = (onepall *)malloc(sizeof(onepall));
  7772. gen->core = &ONE_POLE_ALL_PASS_CLASS;
  7773. gen->size = size;
  7774. gen->x = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  7775. gen->y = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  7776. gen->coeff = coeff;
  7777. if (size == 1)
  7778. gen->f = one_pole_all_pass_1;
  7779. else
  7780. {
  7781. if (size == 8)
  7782. gen->f = one_pole_all_pass_8;
  7783. else gen->f = one_pole_all_pass_n;
  7784. }
  7785. return((mus_any *)gen);
  7786. }
  7787. bool mus_is_one_pole_all_pass(mus_any *ptr)
  7788. {
  7789. return((ptr) &&
  7790. (ptr->core->type == MUS_ONE_POLE_ALL_PASS));
  7791. }
  7792. /* ---------------- env ---------------- */
  7793. typedef enum {MUS_ENV_LINEAR, MUS_ENV_EXPONENTIAL, MUS_ENV_STEP} mus_env_t;
  7794. typedef struct {
  7795. mus_any_class *core;
  7796. mus_float_t rate, current_value, base, offset, scaler, power, init_y, init_power, original_scaler, original_offset;
  7797. mus_long_t loc, end;
  7798. mus_env_t style;
  7799. int index, size;
  7800. mus_float_t *original_data;
  7801. mus_float_t *rates;
  7802. mus_long_t *locs;
  7803. mus_float_t (*env_func)(mus_any *g);
  7804. void *next;
  7805. void (*free_env)(mus_any *ptr);
  7806. } seg;
  7807. /* I used to use exp directly, but:
  7808. (define (texp1 start end num)
  7809. (let* ((ls (log start))
  7810. (le (log end))
  7811. (cf (exp (/ (- le ls) (1- num))))
  7812. (max-diff 0.0)
  7813. (xstart start))
  7814. (do ((i 0 (+ i 1)))
  7815. ((= i num)
  7816. max-diff)
  7817. (let ((val1 (* start (exp (* (/ i (1- num)) (- le ls)))))
  7818. (val2 xstart))
  7819. (set! xstart (* xstart cf))
  7820. (set! max-diff (max max-diff (abs (- val1 val2))))))))
  7821. returns:
  7822. :(texp1 1.0 3.0 1000000)
  7823. 2.65991229042584e-10
  7824. :(texp1 1.0 10.0 100000000)
  7825. 2.24604939091932e-8
  7826. :(texp1 10.0 1000.0 100000000)
  7827. 4.11786902532185e-6
  7828. :(texp1 1.0 1.1 100000000)
  7829. 1.28246036013024e-9
  7830. :(texp1 10.0 1000.0 1000000000)
  7831. 4.39423240550241e-5
  7832. so the repeated multiply version is more than accurate enough
  7833. */
  7834. bool mus_is_env(mus_any *ptr)
  7835. {
  7836. return((ptr) &&
  7837. (ptr->core->type == MUS_ENV));
  7838. }
  7839. mus_float_t mus_env(mus_any *ptr)
  7840. {
  7841. seg *gen = (seg *)ptr;
  7842. return((*(gen->env_func))(ptr));
  7843. }
  7844. mus_float_t (*mus_env_function(mus_any *g))(mus_any *gen)
  7845. {
  7846. if (mus_is_env(g))
  7847. return(((seg *)g)->env_func);
  7848. return(NULL);
  7849. }
  7850. static mus_float_t mus_env_step(mus_any *ptr)
  7851. {
  7852. seg *gen = (seg *)ptr;
  7853. mus_float_t val;
  7854. val = gen->current_value;
  7855. if (gen->loc == 0)
  7856. {
  7857. gen->index++;
  7858. gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1];
  7859. gen->rate = gen->rates[gen->index];
  7860. gen->current_value = gen->rate;
  7861. }
  7862. gen->loc--;
  7863. return(val);
  7864. }
  7865. static mus_float_t mus_env_line(mus_any *ptr)
  7866. {
  7867. seg *gen = (seg *)ptr;
  7868. return(gen->current_value);
  7869. }
  7870. static mus_float_t mus_env_linear(mus_any *ptr)
  7871. {
  7872. seg *gen = (seg *)ptr;
  7873. mus_float_t val;
  7874. val = gen->current_value;
  7875. if (gen->loc == 0)
  7876. {
  7877. /* we can save about 10% total env time by checking here that we're on the last segment,
  7878. * and setting gen->env_func to a version of mus_env_linear that does not watch gen->loc.
  7879. * In any case, this code is strange -- change anything and it is 20% slower, sez callgrind.
  7880. */
  7881. gen->index++;
  7882. gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1];
  7883. gen->rate = gen->rates[gen->index];
  7884. }
  7885. gen->current_value += gen->rate;
  7886. gen->loc--;
  7887. return(val);
  7888. }
  7889. static mus_float_t mus_env_exponential(mus_any *ptr)
  7890. {
  7891. seg *gen = (seg *)ptr;
  7892. mus_float_t val;
  7893. val = gen->current_value;
  7894. if (gen->loc == 0)
  7895. {
  7896. gen->index++;
  7897. gen->loc = gen->locs[gen->index] - gen->locs[gen->index - 1];
  7898. gen->rate = gen->rates[gen->index];
  7899. }
  7900. gen->power *= gen->rate;
  7901. gen->current_value = gen->offset + (gen->scaler * gen->power);
  7902. gen->loc--;
  7903. return(val);
  7904. }
  7905. static mus_float_t run_env(mus_any *ptr, mus_float_t unused1, mus_float_t unused2)
  7906. {
  7907. return(mus_env(ptr));
  7908. }
  7909. static void canonicalize_env(seg *e, const mus_float_t *data, int pts, mus_long_t dur, mus_float_t scaler)
  7910. {
  7911. int i, j, pts2;
  7912. mus_float_t xscl, cur_loc, x1, y1, xdur;
  7913. mus_long_t samps, pre_loc;
  7914. /* pts > 1 if we get here, so the loop below is always exercised */
  7915. pts2 = pts * 2;
  7916. xdur = data[pts2 - 2] - data[0];
  7917. if (xdur > 0.0)
  7918. xscl = (mus_float_t)(dur - 1) / xdur;
  7919. else xscl = 1.0;
  7920. e->locs[pts - 2] = e->end;
  7921. x1 = data[0];
  7922. y1 = data[1];
  7923. pre_loc = 0;
  7924. for (j = 0, i = 2, cur_loc = 0.0; i < pts2; i += 2, j++)
  7925. {
  7926. mus_float_t cur_dx, x0, y0;
  7927. x0 = x1;
  7928. x1 = data[i];
  7929. y0 = y1;
  7930. y1 = data[i + 1];
  7931. cur_dx = xscl * (x1 - x0);
  7932. if (cur_dx < 1.0)
  7933. cur_loc += 1.0;
  7934. else cur_loc += cur_dx;
  7935. switch (e->style)
  7936. {
  7937. case MUS_ENV_LINEAR:
  7938. e->locs[j] = (mus_long_t)(cur_loc + 0.5);
  7939. samps = e->locs[j] - pre_loc;
  7940. pre_loc = e->locs[j];
  7941. if (samps == 0)
  7942. e->rates[j] = 0.0;
  7943. else e->rates[j] = scaler * (y1 - y0) / (mus_float_t)samps;
  7944. break;
  7945. case MUS_ENV_EXPONENTIAL:
  7946. e->locs[j] = (mus_long_t)(cur_loc + 0.5);
  7947. samps = e->locs[j] - pre_loc;
  7948. pre_loc = e->locs[j];
  7949. if (samps == 0)
  7950. e->rates[j] = 1.0;
  7951. else e->rates[j] = exp((y1 - y0) / (mus_float_t)samps);
  7952. break;
  7953. case MUS_ENV_STEP:
  7954. e->locs[j] = (mus_long_t)cur_loc; /* this is the change boundary (confusing...) */
  7955. e->rates[j] = e->offset + (scaler * y0);
  7956. break;
  7957. }
  7958. }
  7959. e->locs[pts - 1] = 1000000000;
  7960. e->locs[pts] = 1000000000; /* guard cell at end to make bounds check simpler */
  7961. }
  7962. static mus_float_t *fixup_exp_env(seg *e, const mus_float_t *data, int pts, mus_float_t offset, mus_float_t scaler, mus_float_t base)
  7963. {
  7964. mus_float_t min_y, max_y, val = 0.0, tmp = 0.0, b1;
  7965. int len, i;
  7966. bool flat;
  7967. mus_float_t *result = NULL;
  7968. if ((base <= 0.0) ||
  7969. (base == 1.0))
  7970. return(NULL);
  7971. min_y = offset + scaler * data[1];
  7972. max_y = min_y;
  7973. len = pts * 2;
  7974. /* fill "result" with x and (offset+scaler*y) */
  7975. result = (mus_float_t *)malloc(len * sizeof(mus_float_t));
  7976. result[0] = data[0];
  7977. result[1] = min_y;
  7978. for (i = 2; i < len; i += 2)
  7979. {
  7980. tmp = offset + scaler * data[i + 1];
  7981. result[i] = data[i];
  7982. result[i + 1] = tmp;
  7983. if (tmp < min_y) min_y = tmp;
  7984. if (tmp > max_y) max_y = tmp;
  7985. }
  7986. b1 = base - 1.0;
  7987. flat = (min_y == max_y);
  7988. if (!flat)
  7989. val = 1.0 / (max_y - min_y);
  7990. /* now logify result */
  7991. for (i = 1; i < len; i += 2)
  7992. {
  7993. if (flat)
  7994. tmp = 1.0;
  7995. else tmp = val * (result[i] - min_y);
  7996. result[i] = log(1.0 + (tmp * b1));
  7997. }
  7998. e->scaler = (max_y - min_y) / b1;
  7999. e->offset = min_y;
  8000. return(result);
  8001. }
  8002. static bool env_equalp(mus_any *p1, mus_any *p2)
  8003. {
  8004. seg *e1 = (seg *)p1;
  8005. seg *e2 = (seg *)p2;
  8006. if (p1 == p2) return(true);
  8007. return((e1) && (e2) &&
  8008. (e1->core->type == e2->core->type) &&
  8009. (e1->loc == e2->loc) &&
  8010. (e1->end == e2->end) &&
  8011. (e1->style == e2->style) &&
  8012. (e1->index == e2->index) &&
  8013. (e1->size == e2->size) &&
  8014. (e1->rate == e2->rate) &&
  8015. (e1->base == e2->base) &&
  8016. (e1->power == e2->power) &&
  8017. (e1->current_value == e2->current_value) &&
  8018. (e1->scaler == e2->scaler) &&
  8019. (e1->offset == e2->offset) &&
  8020. (e1->init_y == e2->init_y) &&
  8021. (e1->init_power == e2->init_power) &&
  8022. (clm_arrays_are_equal(e1->original_data, e2->original_data, e1->size * 2)));
  8023. }
  8024. static char *describe_env(mus_any *ptr)
  8025. {
  8026. char *str = NULL;
  8027. seg *e = (seg *)ptr;
  8028. char *describe_buffer;
  8029. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  8030. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s, pass: %lld (dur: %lld), index: %d, scaler: %.4f, offset: %.4f, data: %s",
  8031. mus_name(ptr),
  8032. ((e->style == MUS_ENV_LINEAR) ? "linear" : ((e->style == MUS_ENV_EXPONENTIAL) ? "exponential" : "step")),
  8033. (e->locs) ? (e->locs[e->index] - e->loc) : -1,
  8034. e->end + 1,
  8035. e->index,
  8036. e->original_scaler,
  8037. e->original_offset,
  8038. str = float_array_to_string(e->original_data, e->size * 2, 0));
  8039. if (str) free(str);
  8040. return(describe_buffer);
  8041. }
  8042. static seg *e2_free_list = NULL, *e3_free_list = NULL, *e4_free_list = NULL;
  8043. static void free_env_gen(mus_any *pt)
  8044. {
  8045. seg *ptr = (seg *)pt;
  8046. (*(ptr->free_env))(pt);
  8047. }
  8048. static void fe2(mus_any *pt)
  8049. {
  8050. seg *ptr = (seg *)pt;
  8051. ptr->next = e2_free_list;
  8052. e2_free_list = ptr;
  8053. }
  8054. static void fe3(mus_any *pt)
  8055. {
  8056. seg *ptr = (seg *)pt;
  8057. ptr->next = e3_free_list;
  8058. e3_free_list = ptr;
  8059. }
  8060. static void fe4(mus_any *pt)
  8061. {
  8062. seg *ptr = (seg *)pt;
  8063. ptr->next = e4_free_list;
  8064. e4_free_list = ptr;
  8065. }
  8066. static void ferest(mus_any *pt)
  8067. {
  8068. seg *ptr = (seg *)pt;
  8069. if (ptr->locs) {free(ptr->locs); ptr->locs = NULL;}
  8070. if (ptr->rates) {free(ptr->rates); ptr->rates = NULL;}
  8071. free(ptr);
  8072. }
  8073. static mus_any *seg_copy(mus_any *ptr)
  8074. {
  8075. seg *e = NULL, *p;
  8076. p = (seg *)ptr;
  8077. switch (p->size) /* "npts" */
  8078. {
  8079. case 1:
  8080. e = (seg *)malloc(sizeof(seg));
  8081. memcpy((void *)e, (void *)ptr, sizeof(seg));
  8082. return((mus_any *)e);
  8083. case 2: if (e2_free_list) {e = e2_free_list; e2_free_list = (seg *)(e->next);} break;
  8084. case 3: if (e3_free_list) {e = e3_free_list; e3_free_list = (seg *)(e->next);} break;
  8085. case 4: if (e4_free_list) {e = e4_free_list; e4_free_list = (seg *)(e->next);} break;
  8086. default: break;
  8087. }
  8088. if (!e)
  8089. {
  8090. e = (seg *)malloc(sizeof(seg));
  8091. memcpy((void *)e, (void *)ptr, sizeof(seg));
  8092. if (p->rates)
  8093. {
  8094. int bytes;
  8095. bytes = p->size * sizeof(mus_float_t);
  8096. e->rates = (mus_float_t *)malloc(bytes);
  8097. memcpy((void *)(e->rates), (void *)(p->rates), bytes);
  8098. bytes = (p->size + 1) * sizeof(mus_long_t);
  8099. e->locs = (mus_long_t *)malloc(bytes);
  8100. memcpy((void *)(e->locs), (void *)(p->locs), bytes);
  8101. }
  8102. }
  8103. else
  8104. {
  8105. mus_float_t *r;
  8106. mus_long_t *l;
  8107. int bytes;
  8108. bytes = p->size * sizeof(mus_float_t);
  8109. r = e->rates;
  8110. memcpy((void *)r, (void *)(p->rates), bytes);
  8111. bytes = (p->size + 1) * sizeof(mus_long_t);
  8112. l = e->locs;
  8113. memcpy((void *)l, (void *)(p->locs), bytes);
  8114. memcpy((void *)e, (void *)ptr, sizeof(seg));
  8115. e->rates = r;
  8116. e->locs = l;
  8117. }
  8118. return((mus_any *)e);
  8119. }
  8120. static mus_float_t *env_data(mus_any *ptr) {return(((seg *)ptr)->original_data);} /* mus-data */
  8121. static mus_float_t env_scaler(mus_any *ptr) {return(((seg *)ptr)->original_scaler);} /* "mus_float_t" for mus-scaler */
  8122. static mus_float_t env_offset(mus_any *ptr) {return(((seg *)ptr)->original_offset);}
  8123. int mus_env_breakpoints(mus_any *ptr) {return(((seg *)ptr)->size);}
  8124. static mus_long_t env_length(mus_any *ptr) {return((((seg *)ptr)->end + 1));} /* this needs to match the :length arg to make-env (changed to +1, 20-Feb-08) */
  8125. static mus_float_t env_current_value(mus_any *ptr) {return(((seg *)ptr)->current_value);}
  8126. mus_long_t *mus_env_passes(mus_any *gen) {return(((seg *)gen)->locs);}
  8127. mus_float_t *mus_env_rates(mus_any *gen) {return(((seg *)gen)->rates);}
  8128. static int env_position(mus_any *ptr) {return(((seg *)ptr)->index);}
  8129. mus_float_t mus_env_offset(mus_any *gen) {return(((seg *)gen)->offset);}
  8130. mus_float_t mus_env_scaler(mus_any *gen) {return(((seg *)gen)->scaler);}
  8131. mus_float_t mus_env_initial_power(mus_any *gen) {return(((seg *)gen)->init_power);}
  8132. static void env_set_location(mus_any *ptr, mus_long_t val);
  8133. static mus_long_t seg_set_pass(mus_any *ptr, mus_long_t val) {env_set_location(ptr, val); return(val);}
  8134. static mus_long_t seg_pass(mus_any *ptr)
  8135. {
  8136. seg *gen = (seg *)ptr;
  8137. return(gen->locs[gen->index] - gen->loc);
  8138. }
  8139. static mus_float_t env_increment(mus_any *rd)
  8140. {
  8141. if (((seg *)rd)->style == MUS_ENV_STEP)
  8142. return(0.0);
  8143. return(((seg *)rd)->base);
  8144. }
  8145. static void env_reset(mus_any *ptr)
  8146. {
  8147. seg *gen = (seg *)ptr;
  8148. gen->current_value = gen->init_y;
  8149. gen->index = 0;
  8150. gen->loc = gen->locs[0];
  8151. gen->rate = gen->rates[0];
  8152. gen->power = gen->init_power;
  8153. }
  8154. static void rebuild_env(seg *e, mus_float_t scl, mus_float_t off, mus_long_t end)
  8155. {
  8156. seg *new_e;
  8157. new_e = (seg *)mus_make_env(e->original_data, e->size, scl, off, e->base, 0.0, end, NULL);
  8158. if (e->locs) free(e->locs);
  8159. if (e->rates) free(e->rates);
  8160. e->locs = new_e->locs;
  8161. e->rates = new_e->rates;
  8162. e->init_y = new_e->init_y;
  8163. e->init_power = new_e->init_power;
  8164. env_reset((mus_any *)e);
  8165. free(new_e);
  8166. }
  8167. static mus_float_t env_set_scaler(mus_any *ptr, mus_float_t val)
  8168. {
  8169. seg *e;
  8170. e = (seg *)ptr;
  8171. rebuild_env(e, val, e->original_offset, e->end);
  8172. e->original_scaler = val;
  8173. return(val);
  8174. }
  8175. static mus_float_t env_set_offset(mus_any *ptr, mus_float_t val)
  8176. {
  8177. seg *e;
  8178. e = (seg *)ptr;
  8179. rebuild_env(e, e->original_scaler, val, e->end);
  8180. e->original_offset = val;
  8181. return(val);
  8182. }
  8183. static mus_long_t env_set_length(mus_any *ptr, mus_long_t val)
  8184. {
  8185. seg *e;
  8186. e = (seg *)ptr;
  8187. rebuild_env(e, e->original_scaler, e->original_offset, val - 1);
  8188. e->end = val - 1;
  8189. return(val);
  8190. }
  8191. static mus_any_class ENV_CLASS = {
  8192. MUS_ENV,
  8193. (char *)S_env,
  8194. &free_env_gen,
  8195. &describe_env,
  8196. &env_equalp,
  8197. &env_data, /* mus-data -> original breakpoints */
  8198. 0,
  8199. &env_length, &env_set_length,
  8200. 0, 0,
  8201. &env_current_value, 0, /* mus-phase?? -- used in snd-sig.c, but this needs a better access point */
  8202. &env_scaler, &env_set_scaler,
  8203. &env_increment,
  8204. 0,
  8205. &run_env,
  8206. MUS_NOT_SPECIAL,
  8207. NULL,
  8208. &env_position,
  8209. &env_offset, &env_set_offset,
  8210. 0, 0, 0, 0, 0, 0, 0, 0,
  8211. 0, 0, 0, 0,
  8212. &seg_pass, &seg_set_pass,
  8213. 0,
  8214. 0, 0, 0, 0,
  8215. &env_reset,
  8216. 0, &seg_copy
  8217. };
  8218. mus_any *mus_make_env(mus_float_t *brkpts, int npts, mus_float_t scaler, mus_float_t offset, mus_float_t base, mus_float_t duration, mus_long_t end, mus_float_t *ignored)
  8219. {
  8220. /* brkpts are not freed by the new env gen when it is freed, but should be protected during its existence */
  8221. int i;
  8222. mus_long_t dur_in_samples;
  8223. mus_float_t *edata;
  8224. seg *e = NULL;
  8225. void (*fe_release)(mus_any *ptr);
  8226. for (i = 2; i < npts * 2; i += 2)
  8227. if (brkpts[i - 2] >= brkpts[i])
  8228. {
  8229. char *temp = NULL;
  8230. mus_error(MUS_BAD_ENVELOPE, S_make_env ": env at breakpoint %d: x axis value: %f <= previous x value: %f (env: %s)",
  8231. i / 2, brkpts[i], brkpts[i - 2],
  8232. temp = float_array_to_string(brkpts, npts * 2, 0)); /* minor memleak here */
  8233. if (temp) free(temp);
  8234. return(NULL);
  8235. }
  8236. switch (npts)
  8237. {
  8238. case 1:
  8239. e = (seg *)calloc(1, sizeof(seg));
  8240. e->core = &ENV_CLASS;
  8241. e->current_value = offset + scaler * brkpts[1];
  8242. e->env_func = mus_env_line;
  8243. e->original_data = brkpts;
  8244. e->free_env = ferest;
  8245. return((mus_any *)e);
  8246. case 2:
  8247. if (e2_free_list)
  8248. {
  8249. e = e2_free_list;
  8250. e2_free_list = (seg *)(e->next);
  8251. }
  8252. fe_release = fe2;
  8253. break;
  8254. case 3:
  8255. if (e3_free_list)
  8256. {
  8257. e = e3_free_list;
  8258. e3_free_list = (seg *)(e->next);
  8259. }
  8260. fe_release = fe3;
  8261. break;
  8262. case 4:
  8263. if (e4_free_list)
  8264. {
  8265. e = e4_free_list;
  8266. e4_free_list = (seg *)(e->next);
  8267. }
  8268. fe_release = fe4;
  8269. break;
  8270. default:
  8271. fe_release = ferest;
  8272. break;
  8273. }
  8274. if (!e)
  8275. {
  8276. e = (seg *)malloc(sizeof(seg));
  8277. e->core = &ENV_CLASS;
  8278. e->size = npts;
  8279. e->rates = (mus_float_t *)malloc(npts * sizeof(mus_float_t));
  8280. e->locs = (mus_long_t *)malloc((npts + 1) * sizeof(mus_long_t));
  8281. }
  8282. e->free_env = fe_release;
  8283. e->original_data = brkpts;
  8284. if (duration != 0.0)
  8285. dur_in_samples = (mus_long_t)(duration * sampling_rate);
  8286. else dur_in_samples = (end + 1);
  8287. e->init_y = offset + scaler * brkpts[1];
  8288. e->current_value = e->init_y;
  8289. e->rate = 0.0;
  8290. e->offset = offset;
  8291. e->scaler = scaler;
  8292. e->original_offset = offset;
  8293. e->original_scaler = scaler;
  8294. e->base = base;
  8295. e->end = (dur_in_samples - 1);
  8296. e->loc = 0;
  8297. e->index = 0;
  8298. if (base == 1.0)
  8299. {
  8300. e->style = MUS_ENV_LINEAR;
  8301. if ((npts == 2) &&
  8302. (brkpts[1] == brkpts[3]))
  8303. e->env_func = mus_env_line;
  8304. else e->env_func = mus_env_linear;
  8305. e->power = 0.0;
  8306. e->init_power = 0.0;
  8307. canonicalize_env(e, brkpts, npts, dur_in_samples, scaler);
  8308. e->rates[npts - 1] = 0.0;
  8309. }
  8310. else
  8311. {
  8312. if (base == 0.0)
  8313. {
  8314. e->style = MUS_ENV_STEP;
  8315. e->env_func = mus_env_step;
  8316. e->power = 0.0;
  8317. e->init_power = 0.0;
  8318. canonicalize_env(e, brkpts, npts, dur_in_samples, scaler);
  8319. e->rates[npts - 1] = e->offset + (scaler * brkpts[npts * 2 - 1]); /* stick at last value, which in this case is the value (not an increment) */
  8320. }
  8321. else
  8322. {
  8323. e->style = MUS_ENV_EXPONENTIAL;
  8324. e->env_func = mus_env_exponential;
  8325. edata = fixup_exp_env(e, brkpts, npts, offset, scaler, base);
  8326. if (edata == NULL)
  8327. {
  8328. free(e);
  8329. return(NULL);
  8330. }
  8331. canonicalize_env(e, edata, npts, dur_in_samples, 1.0);
  8332. e->rates[npts - 1] = 1.0;
  8333. e->power = exp(edata[1]);
  8334. e->init_power = e->power;
  8335. e->offset -= e->scaler;
  8336. free(edata);
  8337. }
  8338. }
  8339. e->rate = e->rates[0];
  8340. e->loc = e->locs[0];
  8341. return((mus_any *)e);
  8342. }
  8343. /* one way to make an impulse: (make-env '(0 1 1 0) :length 1 :base 0.0)
  8344. * a counter: (make-env '(0 0 1 1) :length 21 :scaler 20) -- length = 1+scaler
  8345. */
  8346. static void env_set_location(mus_any *ptr, mus_long_t val)
  8347. {
  8348. seg *gen = (seg *)ptr;
  8349. mus_long_t ctr = 0, loc;
  8350. loc = gen->locs[gen->index] - gen->loc;
  8351. if (loc == val) return;
  8352. if (loc > val)
  8353. mus_reset(ptr);
  8354. else ctr = loc;
  8355. while ((gen->index < (gen->size - 1)) && /* this was gen->size */
  8356. (ctr < val))
  8357. {
  8358. mus_long_t samps;
  8359. if (val > gen->locs[gen->index])
  8360. samps = gen->locs[gen->index] - ctr;
  8361. else samps = val - ctr;
  8362. switch (gen->style)
  8363. {
  8364. case MUS_ENV_LINEAR:
  8365. gen->current_value += (samps * gen->rate);
  8366. break;
  8367. case MUS_ENV_STEP:
  8368. gen->current_value = gen->rate;
  8369. break;
  8370. case MUS_ENV_EXPONENTIAL:
  8371. gen->power *= exp(samps * log(gen->rate));
  8372. gen->current_value = gen->offset + (gen->scaler * gen->power);
  8373. break;
  8374. }
  8375. ctr += samps;
  8376. if (ctr < val)
  8377. {
  8378. gen->index++;
  8379. if (gen->index < gen->size)
  8380. gen->rate = gen->rates[gen->index];
  8381. }
  8382. }
  8383. gen->loc = gen->locs[gen->index] - ctr;
  8384. }
  8385. mus_float_t mus_env_interp(mus_float_t x, mus_any *ptr)
  8386. {
  8387. /* the accuracy depends on the duration here -- more samples = more accurate */
  8388. seg *gen = (seg *)ptr;
  8389. env_set_location(ptr, (mus_long_t)((x * (gen->end + 1)) / (gen->original_data[gen->size * 2 - 2])));
  8390. return(gen->current_value);
  8391. }
  8392. mus_float_t mus_env_any(mus_any *e, mus_float_t (*connect_points)(mus_float_t val))
  8393. {
  8394. /* "env_any" is supposed to mimic "out-any" */
  8395. seg *gen = (seg *)e;
  8396. mus_float_t *pts;
  8397. int pt, size;
  8398. mus_float_t y0, y1, new_val, val;
  8399. mus_float_t scaler, offset;
  8400. scaler = gen->original_scaler;
  8401. offset = gen->original_offset;
  8402. size = gen->size;
  8403. if (size <= 1)
  8404. return(offset + scaler * connect_points(0.0));
  8405. pts = gen->original_data;
  8406. pt = gen->index;
  8407. if (pt >= (size - 1)) pt = size - 2;
  8408. if (pts[pt * 2 + 1] <= pts[pt * 2 + 3])
  8409. {
  8410. y0 = pts[pt * 2 + 1];
  8411. y1 = pts[pt * 2 + 3];
  8412. }
  8413. else
  8414. {
  8415. y1 = pts[pt * 2 + 1];
  8416. y0 = pts[pt * 2 + 3];
  8417. }
  8418. val = (mus_env(e) - offset) / scaler;
  8419. new_val = connect_points( (val - y0) / (y1 - y0));
  8420. return(offset + scaler * (y0 + new_val * (y1 - y0)));
  8421. }
  8422. /* ---------------- pulsed-env ---------------- */
  8423. typedef struct {
  8424. mus_any_class *core;
  8425. mus_any *e, *p;
  8426. bool gens_allocated;
  8427. } plenv;
  8428. static void free_pulsed_env(mus_any *ptr)
  8429. {
  8430. plenv *g;
  8431. g = (plenv *)ptr;
  8432. if (g->gens_allocated)
  8433. {
  8434. mus_free(g->e);
  8435. mus_free(g->p);
  8436. }
  8437. free(ptr);
  8438. }
  8439. static mus_any *plenv_copy(mus_any *ptr)
  8440. {
  8441. plenv *g, *p;
  8442. p = (plenv *)ptr;
  8443. g = (plenv *)malloc(sizeof(plenv));
  8444. memcpy((void *)g, (void *)ptr, sizeof(plenv));
  8445. g->gens_allocated = true;
  8446. g->e = mus_copy(p->e);
  8447. g->p = mus_copy(p->p);
  8448. return((mus_any *)g);
  8449. }
  8450. static mus_float_t run_pulsed_env(mus_any *ptr, mus_float_t input, mus_float_t unused)
  8451. {
  8452. return(mus_pulsed_env(ptr, input));
  8453. }
  8454. static void pulsed_env_reset(mus_any *ptr)
  8455. {
  8456. plenv *pl = (plenv *)ptr;
  8457. mus_reset(pl->e);
  8458. mus_reset(pl->p);
  8459. }
  8460. static bool pulsed_env_equalp(mus_any *p1, mus_any *p2)
  8461. {
  8462. plenv *f1 = (plenv *)p1;
  8463. plenv *f2 = (plenv *)p2;
  8464. if (f1 == f2) return(true);
  8465. return((env_equalp(f1->e, f2->e)) &&
  8466. (sw_equalp(f1->p, f2->p)));
  8467. }
  8468. static char *describe_pulsed_env(mus_any *ptr)
  8469. {
  8470. char *describe_buffer;
  8471. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  8472. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s",
  8473. mus_name(ptr));
  8474. return(describe_buffer);
  8475. }
  8476. static mus_any_class PULSED_ENV_CLASS = {
  8477. MUS_PULSED_ENV,
  8478. (char *)S_pulsed_env,
  8479. &free_pulsed_env,
  8480. &describe_pulsed_env,
  8481. &pulsed_env_equalp,
  8482. 0, 0,
  8483. 0, 0,
  8484. 0, 0,
  8485. 0, 0,
  8486. 0, 0,
  8487. 0, 0,
  8488. &run_pulsed_env,
  8489. MUS_NOT_SPECIAL,
  8490. NULL, 0,
  8491. 0, 0, 0, 0,
  8492. 0, 0,
  8493. 0, 0, 0, 0,
  8494. 0, 0, 0, 0, 0, 0, 0,
  8495. 0, 0, 0, 0,
  8496. &pulsed_env_reset,
  8497. 0, &plenv_copy
  8498. };
  8499. mus_any *mus_make_pulsed_env(mus_any *e, mus_any *p)
  8500. {
  8501. plenv *gen;
  8502. gen = (plenv *)malloc(sizeof(plenv));
  8503. gen->core = &PULSED_ENV_CLASS;
  8504. gen->e = e;
  8505. gen->p = p;
  8506. gen->gens_allocated = false;
  8507. return((mus_any *)gen);
  8508. }
  8509. bool mus_is_pulsed_env(mus_any *ptr)
  8510. {
  8511. return((ptr) &&
  8512. (ptr->core->type == MUS_PULSED_ENV));
  8513. }
  8514. mus_float_t mus_pulsed_env(mus_any *g, mus_float_t inval)
  8515. {
  8516. plenv *pl = (plenv *)g;
  8517. mus_float_t pt_val;
  8518. pt_val = mus_pulse_train(pl->p, inval);
  8519. if (pt_val > 0.1)
  8520. mus_reset(pl->e);
  8521. return(mus_env(pl->e));
  8522. }
  8523. mus_float_t mus_pulsed_env_unmodulated(mus_any *g)
  8524. {
  8525. plenv *pl = (plenv *)g;
  8526. mus_float_t pt_val;
  8527. pt_val = mus_pulse_train_unmodulated(pl->p);
  8528. if (pt_val > 0.1)
  8529. mus_reset(pl->e);
  8530. return(mus_env(pl->e));
  8531. }
  8532. /* ---------------- input/output ---------------- */
  8533. static mus_float_t mus_read_sample(mus_any *fd, mus_long_t frample, int chan)
  8534. {
  8535. if ((check_gen(fd, "mus-read-sample")) &&
  8536. ((fd->core)->read_sample))
  8537. return(((*(fd->core)->read_sample))(fd, frample, chan));
  8538. return((mus_float_t)mus_error(MUS_NO_SAMPLE_INPUT,
  8539. ":can't find %s's sample input function",
  8540. mus_name(fd)));
  8541. }
  8542. char *mus_file_name(mus_any *gen)
  8543. {
  8544. if ((check_gen(gen, S_mus_file_name)) &&
  8545. (gen->core->file_name))
  8546. return((*(gen->core->file_name))(gen));
  8547. else mus_error(MUS_NO_FILE_NAME, "can't get %s's file name", mus_name(gen));
  8548. return(NULL);
  8549. }
  8550. bool mus_is_input(mus_any *gen)
  8551. {
  8552. return((gen) &&
  8553. (gen->core->extended_type == MUS_INPUT));
  8554. }
  8555. bool mus_is_output(mus_any *gen)
  8556. {
  8557. return((gen) &&
  8558. (gen->core->extended_type == MUS_OUTPUT));
  8559. }
  8560. /* ---------------- file->sample ---------------- */
  8561. typedef struct {
  8562. mus_any_class *core;
  8563. int chan;
  8564. int dir;
  8565. mus_long_t loc;
  8566. char *file_name;
  8567. int chans;
  8568. mus_float_t **ibufs, **saved_data;
  8569. mus_float_t *sbuf;
  8570. mus_long_t data_start, data_end, file_end;
  8571. mus_long_t file_buffer_size;
  8572. mus_float_t (*reader)(mus_any *ptr);
  8573. } rdin;
  8574. static char *describe_file_to_sample(mus_any *ptr)
  8575. {
  8576. rdin *gen = (rdin *)ptr;
  8577. char *describe_buffer;
  8578. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  8579. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s",
  8580. mus_name(ptr),
  8581. gen->file_name);
  8582. return(describe_buffer);
  8583. }
  8584. static bool rdin_equalp(mus_any *p1, mus_any *p2)
  8585. {
  8586. rdin *r1 = (rdin *)p1;
  8587. rdin *r2 = (rdin *)p2;
  8588. return((p1 == p2) ||
  8589. ((r1) && (r2) &&
  8590. (r1->core->type == r2->core->type) &&
  8591. (r1->chan == r2->chan) &&
  8592. (r1->loc == r2->loc) &&
  8593. (r1->dir == r2->dir) &&
  8594. (r1->file_name) &&
  8595. (r2->file_name) &&
  8596. (strcmp(r1->file_name, r2->file_name) == 0)));
  8597. }
  8598. static void free_file_to_sample(mus_any *p)
  8599. {
  8600. rdin *ptr = (rdin *)p;
  8601. if (ptr->core->end) ((*ptr->core->end))(p);
  8602. free(ptr->file_name);
  8603. free(ptr);
  8604. }
  8605. static mus_long_t make_ibufs(rdin *gen)
  8606. {
  8607. int i;
  8608. mus_long_t len;
  8609. len = gen->file_end + 1;
  8610. if (len > gen->file_buffer_size)
  8611. len = gen->file_buffer_size;
  8612. gen->ibufs = (mus_float_t **)malloc(gen->chans * sizeof(mus_float_t *));
  8613. for (i = 0; i < gen->chans; i++)
  8614. gen->ibufs[i] = (mus_float_t *)malloc(len * sizeof(mus_float_t));
  8615. return(len);
  8616. }
  8617. static mus_any *rdin_copy(mus_any *ptr)
  8618. {
  8619. rdin *g, *p;
  8620. p = (rdin *)ptr;
  8621. g = (rdin *)malloc(sizeof(rdin));
  8622. memcpy((void *)g, (void *)ptr, sizeof(rdin));
  8623. g->file_name = mus_strdup(p->file_name);
  8624. if (p->ibufs)
  8625. {
  8626. int i;
  8627. mus_long_t len;
  8628. len = make_ibufs(g);
  8629. for (i = 0; i < g->chans; i++)
  8630. memcpy((void *)(g->ibufs[i]), (void *)(p->ibufs[i]), len * sizeof(mus_float_t));
  8631. }
  8632. return((mus_any *)g);
  8633. }
  8634. static mus_long_t file_to_sample_length(mus_any *ptr) {return((((rdin *)ptr)->file_end));}
  8635. static int file_to_sample_channels(mus_any *ptr) {return((int)(((rdin *)ptr)->chans));}
  8636. static mus_float_t file_to_sample_increment(mus_any *rd) {return((mus_float_t)(((rdin *)rd)->dir));}
  8637. static mus_float_t file_to_sample_set_increment(mus_any *rd, mus_float_t val) {((rdin *)rd)->dir = (int)val; return(val);}
  8638. static char *file_to_sample_file_name(mus_any *ptr) {return(((rdin *)ptr)->file_name);}
  8639. static void no_reset(mus_any *ptr) {}
  8640. static mus_float_t mus_in_any_from_file(mus_any *ptr, mus_long_t samp, int chan)
  8641. {
  8642. /* check in-core buffer bounds,
  8643. * if needed read new buffer (taking into account dir)
  8644. * return mus_float_t at samp (frample)
  8645. */
  8646. rdin *gen = (rdin *)ptr;
  8647. if (chan >= gen->chans)
  8648. return(0.0);
  8649. if ((samp <= gen->data_end) &&
  8650. (samp >= gen->data_start))
  8651. return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start]));
  8652. if ((samp >= 0) &&
  8653. (samp < gen->file_end))
  8654. {
  8655. /* got to read it from the file */
  8656. int fd;
  8657. mus_long_t newloc;
  8658. /* read in first buffer start either at samp (dir > 0) or samp-bufsize (dir < 0) */
  8659. if (samp >= gen->data_start) /* gen dir is irrelevant here (see grev in clm23.scm) */
  8660. newloc = samp;
  8661. else newloc = (mus_long_t)(samp - (gen->file_buffer_size * .75));
  8662. /* The .75 in the backwards read is trying to avoid reading the full buffer on
  8663. * nearly every sample when we're oscillating around the
  8664. * nominal buffer start/end (in src driven by an oscil for example)
  8665. */
  8666. if (newloc < 0) newloc = 0;
  8667. gen->data_start = newloc;
  8668. gen->data_end = newloc + gen->file_buffer_size - 1;
  8669. fd = mus_sound_open_input(gen->file_name);
  8670. if (fd == -1)
  8671. return((mus_float_t)mus_error(MUS_CANT_OPEN_FILE,
  8672. "open(%s) -> %s",
  8673. gen->file_name, STRERROR(errno)));
  8674. else
  8675. {
  8676. if (gen->ibufs == NULL)
  8677. make_ibufs(gen);
  8678. mus_file_seek_frample(fd, gen->data_start);
  8679. if ((gen->data_start + gen->file_buffer_size) >= gen->file_end)
  8680. mus_file_read_chans(fd, gen->data_start, gen->file_end - gen->data_start, gen->chans, gen->ibufs, gen->ibufs);
  8681. else mus_file_read_chans(fd, gen->data_start, gen->file_buffer_size, gen->chans, gen->ibufs, gen->ibufs);
  8682. /* we have to check file_end here because chunked files can have trailing chunks containing
  8683. * comments or whatever. io.c (mus_file_read_*) merely calls read, and translates bytes --
  8684. * if it gets fewer than requested, it zeros from the point where the incoming file data stopped,
  8685. * but that can be far beyond the actual end of the sample data! It is at this level that
  8686. * we know how much data is actually supposed to be in the file.
  8687. *
  8688. * Also, file_end is the number of framples, so we should not read samp # file_end (see above).
  8689. */
  8690. mus_sound_close_input(fd);
  8691. if (gen->data_end > gen->file_end) gen->data_end = gen->file_end;
  8692. }
  8693. return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start]));
  8694. }
  8695. return(0.0);
  8696. }
  8697. static mus_float_t run_file_to_sample(mus_any *ptr, mus_float_t arg1, mus_float_t arg2)
  8698. {
  8699. /* mus_read_sample here? */
  8700. return(mus_in_any_from_file(ptr, (int)arg1, (int)arg2));
  8701. }
  8702. static int file_to_sample_end(mus_any *ptr)
  8703. {
  8704. rdin *gen = (rdin *)ptr;
  8705. if (gen)
  8706. {
  8707. if (gen->ibufs)
  8708. {
  8709. int i;
  8710. for (i = 0; i < gen->chans; i++)
  8711. if (gen->ibufs[i])
  8712. free(gen->ibufs[i]);
  8713. free(gen->ibufs);
  8714. gen->ibufs = NULL;
  8715. gen->sbuf = NULL;
  8716. }
  8717. }
  8718. return(0);
  8719. }
  8720. static mus_any_class FILE_TO_SAMPLE_CLASS = {
  8721. MUS_FILE_TO_SAMPLE,
  8722. (char *)S_file_to_sample,
  8723. &free_file_to_sample,
  8724. &describe_file_to_sample,
  8725. &rdin_equalp,
  8726. 0, 0,
  8727. &file_to_sample_length, 0,
  8728. 0, 0, 0, 0,
  8729. 0, 0,
  8730. &file_to_sample_increment,
  8731. &file_to_sample_set_increment,
  8732. &run_file_to_sample,
  8733. MUS_INPUT,
  8734. NULL,
  8735. &file_to_sample_channels,
  8736. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  8737. &mus_in_any_from_file,
  8738. 0,
  8739. &file_to_sample_file_name,
  8740. &file_to_sample_end,
  8741. 0, /* location */
  8742. 0, /* set_location */
  8743. 0, /* channel */
  8744. 0, 0, 0, 0,
  8745. &no_reset,
  8746. 0, &rdin_copy
  8747. };
  8748. bool mus_is_file_to_sample(mus_any *ptr)
  8749. {
  8750. return((ptr) &&
  8751. (ptr->core->type == MUS_FILE_TO_SAMPLE));
  8752. }
  8753. mus_any *mus_make_file_to_sample_with_buffer_size(const char *filename, mus_long_t buffer_size)
  8754. {
  8755. rdin *gen;
  8756. if (filename == NULL)
  8757. mus_error(MUS_NO_FILE_NAME_PROVIDED, S_make_file_to_sample " requires a file name");
  8758. else
  8759. {
  8760. gen = (rdin *)calloc(1, sizeof(rdin));
  8761. gen->core = &FILE_TO_SAMPLE_CLASS;
  8762. gen->file_name = (char *)malloc((strlen(filename) + 1) * sizeof(char));
  8763. strcpy(gen->file_name, filename);
  8764. gen->data_end = -1; /* force initial read */
  8765. gen->chans = mus_sound_chans(gen->file_name);
  8766. if (gen->chans <= 0)
  8767. mus_error(MUS_NO_CHANNELS, S_make_file_to_sample ": %s chans: %d", filename, gen->chans);
  8768. gen->file_end = mus_sound_framples(gen->file_name);
  8769. if (gen->file_end < 0)
  8770. mus_error(MUS_NO_LENGTH, S_make_file_to_sample ": %s framples: %lld", filename, gen->file_end);
  8771. if (buffer_size < gen->file_end)
  8772. gen->file_buffer_size = buffer_size;
  8773. else gen->file_buffer_size = gen->file_end;
  8774. return((mus_any *)gen);
  8775. }
  8776. return(NULL);
  8777. }
  8778. mus_any *mus_make_file_to_sample(const char *filename)
  8779. {
  8780. return(mus_make_file_to_sample_with_buffer_size(filename, clm_file_buffer_size));
  8781. }
  8782. mus_float_t mus_file_to_sample(mus_any *ptr, mus_long_t samp, int chan)
  8783. {
  8784. rdin *gen = (rdin *)ptr;
  8785. if (chan >= gen->chans)
  8786. return(0.0);
  8787. /* redundant in a sense, but saves the call overhead of mus_in_any_from_file */
  8788. if ((samp <= gen->data_end) &&
  8789. (samp >= gen->data_start))
  8790. return((mus_float_t)(gen->ibufs[chan][samp - gen->data_start]));
  8791. return(mus_in_any_from_file(ptr, samp, chan));
  8792. }
  8793. /* ---------------- readin ---------------- */
  8794. /* readin reads only the desired channel and increments the location by the direction
  8795. * it inherits from and specializes the file_to_sample class
  8796. */
  8797. static char *describe_readin(mus_any *ptr)
  8798. {
  8799. rdin *gen = (rdin *)ptr;
  8800. char *describe_buffer;
  8801. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  8802. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s[chan %d], loc: %lld, dir: %d",
  8803. mus_name(ptr),
  8804. gen->file_name, gen->chan, gen->loc, gen->dir);
  8805. return(describe_buffer);
  8806. }
  8807. static void free_readin(mus_any *p)
  8808. {
  8809. rdin *ptr = (rdin *)p;
  8810. if (ptr->core->end) ((*ptr->core->end))(p);
  8811. free(ptr->file_name);
  8812. free(ptr);
  8813. }
  8814. static mus_float_t run_readin(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(((rdin *)ptr)->reader(ptr));}
  8815. static mus_float_t readin_to_sample(mus_any *ptr, mus_long_t samp, int chan) {return(((rdin *)ptr)->reader(ptr));}
  8816. static mus_float_t rd_increment(mus_any *ptr) {return((mus_float_t)(((rdin *)ptr)->dir));}
  8817. static mus_float_t rd_set_increment(mus_any *ptr, mus_float_t val) {((rdin *)ptr)->dir = (int)val; return(val);}
  8818. static mus_long_t rd_location(mus_any *rd) {return(((rdin *)rd)->loc);}
  8819. static mus_long_t rd_set_location(mus_any *rd, mus_long_t loc) {((rdin *)rd)->loc = loc; return(loc);}
  8820. static int rd_channel(mus_any *rd) {return(((rdin *)rd)->chan);}
  8821. static mus_any_class READIN_CLASS = {
  8822. MUS_READIN,
  8823. (char *)S_readin,
  8824. &free_readin,
  8825. &describe_readin,
  8826. &rdin_equalp,
  8827. 0, 0,
  8828. &file_to_sample_length, 0,
  8829. 0, 0, 0, 0,
  8830. &fallback_scaler, 0,
  8831. &rd_increment,
  8832. &rd_set_increment,
  8833. &run_readin,
  8834. MUS_INPUT,
  8835. NULL,
  8836. &file_to_sample_channels,
  8837. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  8838. &readin_to_sample,
  8839. 0,
  8840. &file_to_sample_file_name,
  8841. &file_to_sample_end,
  8842. &rd_location,
  8843. &rd_set_location,
  8844. &rd_channel,
  8845. 0, 0, 0, 0,
  8846. &no_reset,
  8847. 0, &rdin_copy
  8848. };
  8849. bool mus_is_readin(mus_any *ptr)
  8850. {
  8851. return((ptr) &&
  8852. (ptr->core->type == MUS_READIN));
  8853. }
  8854. mus_float_t mus_readin(mus_any *ptr)
  8855. {
  8856. return(((rdin *)ptr)->reader(ptr));
  8857. }
  8858. static mus_float_t safe_readin(mus_any *ptr)
  8859. {
  8860. mus_float_t res;
  8861. rdin *rd = (rdin *)ptr;
  8862. if ((rd->loc < rd->file_end) &&
  8863. (rd->loc >= 0))
  8864. res = rd->sbuf[rd->loc];
  8865. else res = 0.0;
  8866. rd->loc += rd->dir;
  8867. return(res);
  8868. }
  8869. static mus_float_t readin(mus_any *ptr)
  8870. {
  8871. mus_float_t res;
  8872. rdin *rd = (rdin *)ptr;
  8873. if ((rd->loc <= rd->data_end) &&
  8874. (rd->loc >= rd->data_start))
  8875. res = rd->sbuf[rd->loc - rd->data_start];
  8876. else
  8877. {
  8878. if ((rd->loc < 0) || (rd->loc >= rd->file_end))
  8879. res = 0.0;
  8880. else res = mus_in_any_from_file(ptr, rd->loc, rd->chan);
  8881. }
  8882. rd->loc += rd->dir;
  8883. return(res);
  8884. }
  8885. mus_any *mus_make_readin_with_buffer_size(const char *filename, int chan, mus_long_t start, int direction, mus_long_t buffer_size)
  8886. {
  8887. rdin *gen;
  8888. if (chan >= mus_sound_chans(filename))
  8889. mus_error(MUS_NO_SUCH_CHANNEL, S_make_readin ": %s, chan: %d, but chans: %d", filename, chan, mus_sound_chans(filename));
  8890. gen = (rdin *)mus_make_file_to_sample(filename);
  8891. if (gen)
  8892. {
  8893. gen->core = &READIN_CLASS;
  8894. gen->loc = start;
  8895. gen->dir = direction;
  8896. gen->chan = chan;
  8897. /* the saved data option does not save us anything in file_to_sample above */
  8898. gen->saved_data = mus_sound_saved_data(filename);
  8899. if (!gen->saved_data)
  8900. {
  8901. char *str;
  8902. str = mus_expand_filename(filename);
  8903. if (str)
  8904. {
  8905. gen->saved_data = mus_sound_saved_data(str);
  8906. free(str);
  8907. }
  8908. }
  8909. if (gen->saved_data)
  8910. {
  8911. gen->file_buffer_size = gen->file_end;
  8912. gen->sbuf = gen->saved_data[chan];
  8913. gen->reader = safe_readin;
  8914. gen->data_start = 0;
  8915. gen->data_end = gen->file_end;
  8916. }
  8917. else
  8918. {
  8919. gen->ibufs = (mus_float_t **)calloc(gen->chans, sizeof(mus_float_t *));
  8920. if (buffer_size > gen->file_end)
  8921. {
  8922. gen->file_buffer_size = gen->file_end;
  8923. gen->reader = safe_readin;
  8924. gen->ibufs[chan] = (mus_float_t *)malloc(gen->file_buffer_size * sizeof(mus_float_t));
  8925. mus_in_any_from_file((mus_any *)gen, 0, chan);
  8926. }
  8927. else
  8928. {
  8929. gen->file_buffer_size = buffer_size;
  8930. gen->reader = readin;
  8931. gen->ibufs[chan] = (mus_float_t *)malloc(gen->file_buffer_size * sizeof(mus_float_t));
  8932. }
  8933. gen->sbuf = gen->ibufs[chan];
  8934. }
  8935. return((mus_any *)gen);
  8936. }
  8937. return(NULL);
  8938. }
  8939. /* it would be easy to extend readin to read from a float-vector by using the saved_data and safe_readin
  8940. * business above -- just need mus_make_readin_from_float_vector or something.
  8941. */
  8942. mus_long_t mus_set_location(mus_any *gen, mus_long_t loc)
  8943. {
  8944. if ((check_gen(gen, S_set S_mus_location)) &&
  8945. (gen->core->set_location))
  8946. return((*(gen->core->set_location))(gen, loc));
  8947. return((mus_long_t)mus_error(MUS_NO_LOCATION, "can't set %s's location", mus_name(gen)));
  8948. }
  8949. /* ---------------- in-any ---------------- */
  8950. mus_float_t mus_in_any(mus_long_t samp, int chan, mus_any *IO)
  8951. {
  8952. if (IO) return(mus_read_sample(IO, samp, chan));
  8953. return(0.0);
  8954. }
  8955. bool mus_in_any_is_safe(mus_any *ptr)
  8956. {
  8957. rdin *gen = (rdin *)ptr;
  8958. return((gen) &&
  8959. ((gen->core->read_sample == mus_in_any_from_file) ||
  8960. (gen->core->read_sample == readin_to_sample)));
  8961. }
  8962. /* ---------------- file->frample ---------------- */
  8963. /* also built on file->sample */
  8964. static char *describe_file_to_frample(mus_any *ptr)
  8965. {
  8966. rdin *gen = (rdin *)ptr;
  8967. char *describe_buffer;
  8968. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  8969. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s",
  8970. mus_name(ptr),
  8971. gen->file_name);
  8972. return(describe_buffer);
  8973. }
  8974. static mus_float_t run_file_to_frample(mus_any *ptr, mus_float_t arg1, mus_float_t arg2)
  8975. {
  8976. mus_error(MUS_NO_RUN, "no run method for file->frample");
  8977. return(0.0);
  8978. }
  8979. static mus_any_class FILE_TO_FRAMPLE_CLASS = {
  8980. MUS_FILE_TO_FRAMPLE,
  8981. (char *)S_file_to_frample,
  8982. &free_file_to_sample,
  8983. &describe_file_to_frample,
  8984. &rdin_equalp,
  8985. 0, 0,
  8986. &file_to_sample_length, 0,
  8987. 0, 0, 0, 0,
  8988. &fallback_scaler, 0,
  8989. &file_to_sample_increment, /* allow backward reads */
  8990. &file_to_sample_set_increment,
  8991. &run_file_to_frample,
  8992. MUS_INPUT,
  8993. NULL,
  8994. &file_to_sample_channels,
  8995. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  8996. &mus_in_any_from_file,
  8997. 0,
  8998. &file_to_sample_file_name,
  8999. &file_to_sample_end,
  9000. 0, /* location */
  9001. 0, /* set_location */
  9002. 0, /* channel */
  9003. 0, 0, 0, 0,
  9004. &no_reset,
  9005. 0, &rdin_copy
  9006. };
  9007. mus_any *mus_make_file_to_frample_with_buffer_size(const char *filename, mus_long_t buffer_size)
  9008. {
  9009. rdin *gen;
  9010. gen = (rdin *)mus_make_file_to_sample_with_buffer_size(filename, buffer_size);
  9011. if (gen)
  9012. {
  9013. gen->core = &FILE_TO_FRAMPLE_CLASS;
  9014. return((mus_any *)gen);
  9015. }
  9016. return(NULL);
  9017. }
  9018. mus_any *mus_make_file_to_frample(const char *filename)
  9019. {
  9020. return(mus_make_file_to_frample_with_buffer_size(filename, clm_file_buffer_size));
  9021. }
  9022. bool mus_is_file_to_frample(mus_any *ptr)
  9023. {
  9024. return((ptr) &&
  9025. (ptr->core->type == MUS_FILE_TO_FRAMPLE));
  9026. }
  9027. mus_float_t *mus_file_to_frample(mus_any *ptr, mus_long_t samp, mus_float_t *f)
  9028. {
  9029. rdin *gen = (rdin *)ptr;
  9030. int i;
  9031. if ((samp <= gen->data_end) &&
  9032. (samp >= gen->data_start))
  9033. {
  9034. mus_long_t pos;
  9035. pos = samp - gen->data_start;
  9036. f[0] = gen->ibufs[0][pos];
  9037. for (i = 1; i < gen->chans; i++)
  9038. f[i] = gen->ibufs[i][pos];
  9039. }
  9040. else
  9041. {
  9042. if ((samp < 0) ||
  9043. (samp >= gen->file_end))
  9044. {
  9045. for (i = 0; i < gen->chans; i++)
  9046. f[i] = 0.0;
  9047. }
  9048. else
  9049. {
  9050. f[0] = mus_in_any_from_file(ptr, samp, 0);
  9051. for (i = 1; i < gen->chans; i++)
  9052. f[i] = mus_in_any_from_file(ptr, samp, i);
  9053. }
  9054. }
  9055. return(f);
  9056. }
  9057. /* ---------------- sample->file ---------------- */
  9058. /* in all output functions, the assumption is that we're adding to whatever already exists */
  9059. /* also, the "end" methods need to flush the output buffer */
  9060. /* rdout struct is in clm.h */
  9061. static char *describe_sample_to_file(mus_any *ptr)
  9062. {
  9063. rdout *gen = (rdout *)ptr;
  9064. char *describe_buffer;
  9065. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  9066. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s",
  9067. mus_name(ptr),
  9068. gen->file_name);
  9069. return(describe_buffer);
  9070. }
  9071. static bool sample_to_file_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  9072. static void free_sample_to_file(mus_any *p)
  9073. {
  9074. rdout *ptr = (rdout *)p;
  9075. if (ptr->core->end) ((*ptr->core->end))(p);
  9076. free(ptr->file_name);
  9077. free(ptr);
  9078. }
  9079. static mus_any *rdout_copy(mus_any *ptr)
  9080. {
  9081. rdout *g, *p;
  9082. p = (rdout *)ptr;
  9083. g = (rdout *)malloc(sizeof(rdout));
  9084. memcpy((void *)g, (void *)ptr, sizeof(rdout));
  9085. g->file_name = mus_strdup(p->file_name);
  9086. if (p->obufs)
  9087. {
  9088. int i;
  9089. mus_long_t bytes;
  9090. bytes = clm_file_buffer_size * sizeof(mus_float_t);
  9091. g->obufs = (mus_float_t **)malloc(g->chans * sizeof(mus_float_t *));
  9092. for (i = 0; i < g->chans; i++)
  9093. {
  9094. g->obufs[i] = (mus_float_t *)malloc(bytes);
  9095. memcpy((void *)(g->obufs[i]), (void *)(p->obufs[i]), bytes);
  9096. }
  9097. g->obuf0 = g->obufs[0];
  9098. if (g->chans > 1)
  9099. g->obuf1 = g->obufs[1];
  9100. else g->obuf1 = NULL;
  9101. }
  9102. return((mus_any *)g);
  9103. }
  9104. static int sample_to_file_channels(mus_any *ptr) {return((int)(((rdout *)ptr)->chans));}
  9105. static mus_long_t bufferlen(mus_any *ptr) {return(clm_file_buffer_size);}
  9106. static mus_long_t set_bufferlen(mus_any *ptr, mus_long_t len) {clm_file_buffer_size = len; return(len);}
  9107. static char *sample_to_file_file_name(mus_any *ptr) {return(((rdout *)ptr)->file_name);}
  9108. static int sample_to_file_end(mus_any *ptr);
  9109. static mus_float_t run_sample_to_file(mus_any *ptr, mus_float_t arg1, mus_float_t arg2) {mus_error(MUS_NO_RUN, "no run method for sample->file"); return(0.0);}
  9110. static mus_any_class SAMPLE_TO_FILE_CLASS = {
  9111. MUS_SAMPLE_TO_FILE,
  9112. (char *)S_sample_to_file,
  9113. &free_sample_to_file,
  9114. &describe_sample_to_file,
  9115. &sample_to_file_equalp,
  9116. 0, 0,
  9117. &bufferlen, &set_bufferlen, /* does this have any effect on the current gen? */
  9118. 0, 0, 0, 0,
  9119. &fallback_scaler, 0,
  9120. 0, 0,
  9121. &run_sample_to_file,
  9122. MUS_OUTPUT,
  9123. NULL,
  9124. &sample_to_file_channels,
  9125. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  9126. 0,
  9127. &mus_out_any_to_file,
  9128. &sample_to_file_file_name,
  9129. &sample_to_file_end,
  9130. 0, 0, 0,
  9131. 0, 0, 0, 0,
  9132. &no_reset,
  9133. 0, &rdout_copy
  9134. };
  9135. static int *sample_type_zero = NULL;
  9136. int mus_sample_type_zero(mus_sample_t samp_type)
  9137. {
  9138. return(sample_type_zero[samp_type]);
  9139. }
  9140. static void flush_buffers(rdout *gen)
  9141. {
  9142. int fd;
  9143. if ((gen->obufs == NULL) ||
  9144. (mus_file_probe(gen->file_name) == 0) ||
  9145. (gen->chans == 0))
  9146. return; /* can happen if output abandoned, then later mus_free called via GC sweep */
  9147. fd = mus_sound_open_input(gen->file_name);
  9148. if (fd == -1)
  9149. {
  9150. /* no output yet, so open the output file and write the current samples (no need to add to existing samples in this case) */
  9151. fd = mus_sound_open_output(gen->file_name,
  9152. (int)sampling_rate,
  9153. gen->chans,
  9154. gen->output_sample_type,
  9155. gen->output_header_type,
  9156. NULL);
  9157. if (fd == -1)
  9158. mus_error(MUS_CANT_OPEN_FILE,
  9159. "open(%s) -> %s",
  9160. gen->file_name, STRERROR(errno));
  9161. else
  9162. {
  9163. mus_file_write(fd, 0, gen->out_end, gen->chans, gen->obufs);
  9164. mus_sound_close_output(fd, (gen->out_end + 1) * gen->chans * mus_bytes_per_sample(mus_sound_sample_type(gen->file_name)));
  9165. }
  9166. }
  9167. else
  9168. {
  9169. /* get existing samples, add new output, write back to output */
  9170. mus_float_t **addbufs = NULL;
  9171. int i;
  9172. mus_sample_t sample_type;
  9173. mus_long_t current_file_framples, framples_to_add;
  9174. sample_type = mus_sound_sample_type(gen->file_name);
  9175. current_file_framples = mus_sound_framples(gen->file_name);
  9176. /* this is often 0 (brand-new file) */
  9177. if (current_file_framples > gen->data_start)
  9178. {
  9179. bool allocation_failed = false;
  9180. addbufs = (mus_float_t **)calloc(gen->chans, sizeof(mus_float_t *));
  9181. for (i = 0; i < gen->chans; i++)
  9182. {
  9183. /* clm_file_buffer_size may be too large, but it's very hard to tell that
  9184. * in advance. In Linux, malloc returns a non-null pointer even when
  9185. * there's no memory available, so you have to touch the memory to force
  9186. * the OS to deal with it, then the next allocation returns null.
  9187. */
  9188. addbufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t));
  9189. if (addbufs[i])
  9190. addbufs[i][0] = 0.0;
  9191. else
  9192. {
  9193. allocation_failed = true;
  9194. break;
  9195. }
  9196. }
  9197. if (allocation_failed)
  9198. {
  9199. mus_long_t old_file_buffer_size = 0;
  9200. /* first clean up the mess we made */
  9201. for (i = 0; i < gen->chans; i++)
  9202. if (addbufs[i])
  9203. {
  9204. free(addbufs[i]);
  9205. addbufs[i] = NULL;
  9206. }
  9207. free(addbufs);
  9208. /* it would take a lot of screwing around to find the biggest clm_file_buffer_size we could handle,
  9209. * and it might fail on the next call (if more chans), so we'll throw an error. We could get
  9210. * say 1024 samps per chan, then run through a loop outputting the current buffer, but geez...
  9211. */
  9212. /* but... if we hit this in with-sound, mus_error calls (eventually) s7_error which sees the
  9213. * dynamic-wind and tries to call mus-close, which tries to flush the buffers and we have
  9214. * an infinite loop. So, we need to clean up right now.
  9215. */
  9216. mus_sound_close_input(fd);
  9217. old_file_buffer_size = clm_file_buffer_size;
  9218. clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE;
  9219. mus_error(MUS_MEMORY_ALLOCATION_FAILED, S_mus_file_buffer_size " (%lld) is too large: we can't allocate the output buffers!", old_file_buffer_size);
  9220. return;
  9221. }
  9222. }
  9223. framples_to_add = gen->out_end - gen->data_start;
  9224. /* if the caller reset clm_file_buffer_size during a run, framples_to_add might be greater than the assumed buffer size,
  9225. * so we need to complain and fix up the limits. In CLM, the size is set in sound.lisp, begin-with-sound.
  9226. * In Snd via mus_set_file_buffer_size in clm2xen.c. The initial default is set in mus_initialize
  9227. * called in CLM by clm-initialize-links via in cmus.c, and in Snd in clm2xen.c when the module is setup.
  9228. */
  9229. if (framples_to_add >= clm_file_buffer_size)
  9230. {
  9231. mus_print("clm-file-buffer-size changed? %lld <= %lld (start: %lld, end: %lld, %lld)",
  9232. clm_file_buffer_size, framples_to_add, gen->data_start, gen->data_end, gen->out_end);
  9233. framples_to_add = clm_file_buffer_size - 1;
  9234. /* this means we drop samples -- the other choice (short of throwing an error) would
  9235. * be to read/allocate the bigger size.
  9236. */
  9237. }
  9238. if (addbufs)
  9239. {
  9240. mus_file_seek_frample(fd, gen->data_start);
  9241. mus_file_read(fd, gen->data_start, framples_to_add + 1, gen->chans, addbufs);
  9242. }
  9243. mus_sound_close_input(fd); /* close previous mus_sound_open_input */
  9244. fd = mus_sound_reopen_output(gen->file_name, gen->chans, sample_type,
  9245. mus_sound_header_type(gen->file_name),
  9246. mus_sound_data_location(gen->file_name));
  9247. if ((current_file_framples < gen->data_start) &&
  9248. (sample_type_zero[sample_type] != 0))
  9249. {
  9250. /* we're about to create a gap in the output file. mus_file_seek_frample calls lseek which (man lseek):
  9251. *
  9252. * "The lseek function allows the file offset to be set beyond the end of
  9253. * the existing end-of-file of the file (but this does not change the size
  9254. * of the file). If data is later written at this point, subsequent reads
  9255. * of the data in the gap return bytes of zeros (until data is actually
  9256. * written into the gap)."
  9257. *
  9258. * but 0 bytes in a file are not interpreted as sound samples of 0 in several sample types.
  9259. * for example, mus-mulaw 0 => -.98, whereas sound sample 0 is a byte of 255.
  9260. * see the table at the end of this file (sample_type_zero) for the other cases.
  9261. *
  9262. * So, we need to write explicit sample-type 0 values in those cases where machine 0's
  9263. * won't be sample type 0. sample_type_zero[type] != 0 signals we have such a
  9264. * case, and returns the nominal zero value. For unsigned shorts, we also need to
  9265. * take endianess into account.
  9266. */
  9267. mus_long_t filler, current_samps, bytes, bps;
  9268. unsigned char *zeros;
  9269. #define MAX_ZERO_SAMPLES 65536
  9270. bps = mus_bytes_per_sample(sample_type);
  9271. filler = gen->data_start - current_file_framples;
  9272. mus_file_seek_frample(fd, current_file_framples);
  9273. if (filler > MAX_ZERO_SAMPLES)
  9274. bytes = MAX_ZERO_SAMPLES * bps * gen->chans;
  9275. else bytes = filler * bps * gen->chans;
  9276. zeros = (unsigned char *)malloc(bytes);
  9277. if (bps == 1)
  9278. memset((void *)zeros, sample_type_zero[sample_type], bytes);
  9279. else /* it has to be a short */
  9280. {
  9281. int df, i, b1, b2;
  9282. df = sample_type_zero[sample_type];
  9283. b1 = df >> 8;
  9284. b2 = df & 0xff;
  9285. for (i = 0; i < bytes; i += 2)
  9286. {
  9287. zeros[i] = b2;
  9288. zeros[i + 1] = b1;
  9289. }
  9290. }
  9291. /* (with-sound (:sample-type mus-ulshort) (fm-violin 10 1 440 .1)) */
  9292. while (filler > 0)
  9293. {
  9294. ssize_t wbytes;
  9295. if (filler > MAX_ZERO_SAMPLES)
  9296. current_samps = MAX_ZERO_SAMPLES;
  9297. else
  9298. {
  9299. current_samps = filler;
  9300. bytes = current_samps * bps * gen->chans;
  9301. }
  9302. wbytes = write(fd, zeros, bytes);
  9303. if (wbytes != bytes) fprintf(stderr, "%s[%d]: write trouble\n", __func__, __LINE__);
  9304. filler -= current_samps;
  9305. }
  9306. free(zeros);
  9307. }
  9308. if (addbufs)
  9309. {
  9310. int j;
  9311. /* fill/write output buffers with current data added to saved data */
  9312. for (j = 0; j < gen->chans; j++)
  9313. {
  9314. mus_float_t *adder, *vals;
  9315. mus_long_t add4;
  9316. adder = addbufs[j];
  9317. vals = gen->obufs[j];
  9318. add4 = framples_to_add - 4;
  9319. i = 0;
  9320. while (i <= add4)
  9321. {
  9322. adder[i] += vals[i];
  9323. i++;
  9324. adder[i] += vals[i];
  9325. i++;
  9326. adder[i] += vals[i];
  9327. i++;
  9328. adder[i] += vals[i];
  9329. i++;
  9330. }
  9331. for (; i <= framples_to_add; i++)
  9332. adder[i] += vals[i];
  9333. }
  9334. mus_file_seek_frample(fd, gen->data_start);
  9335. mus_file_write(fd, 0, framples_to_add, gen->chans, addbufs);
  9336. for (i = 0; i < gen->chans; i++)
  9337. free(addbufs[i]);
  9338. free(addbufs);
  9339. }
  9340. else
  9341. {
  9342. /* output currently empty, so just flush out the gen->obufs */
  9343. mus_file_seek_frample(fd, gen->data_start);
  9344. mus_file_write(fd, 0, framples_to_add, gen->chans, gen->obufs);
  9345. }
  9346. if (current_file_framples <= gen->out_end)
  9347. current_file_framples = gen->out_end + 1;
  9348. mus_sound_close_output(fd, current_file_framples * gen->chans * mus_bytes_per_sample(sample_type));
  9349. }
  9350. }
  9351. mus_any *mus_sample_to_file_add(mus_any *out1, mus_any *out2)
  9352. {
  9353. mus_long_t min_framples;
  9354. rdout *dest = (rdout *)out1;
  9355. rdout *in_coming = (rdout *)out2;
  9356. int chn, min_chans;
  9357. min_chans = dest->chans;
  9358. if (in_coming->chans < min_chans) min_chans = in_coming->chans;
  9359. min_framples = in_coming->out_end;
  9360. for (chn = 0; chn < min_chans; chn++)
  9361. {
  9362. mus_long_t i;
  9363. for (i = 0; i < min_framples; i++)
  9364. dest->obufs[chn][i] += in_coming->obufs[chn][i];
  9365. memset((void *)(in_coming->obufs[chn]), 0, min_framples * sizeof(mus_float_t));
  9366. }
  9367. if (min_framples > dest->out_end)
  9368. dest->out_end = min_framples;
  9369. in_coming->out_end = 0;
  9370. in_coming->data_start = 0;
  9371. return((mus_any*)dest);
  9372. }
  9373. mus_float_t mus_out_any_to_file(mus_any *ptr, mus_long_t samp, int chan, mus_float_t val)
  9374. {
  9375. rdout *gen = (rdout *)ptr;
  9376. if (!ptr) return(val);
  9377. if ((chan >= gen->chans) || /* checking for (val == 0.0) here appears to make no difference overall */
  9378. (!(gen->obufs)))
  9379. return(val);
  9380. if ((samp <= gen->data_end) &&
  9381. (samp >= gen->data_start))
  9382. gen->obufs[chan][samp - gen->data_start] += val;
  9383. else
  9384. {
  9385. int j;
  9386. if (samp < 0) return(val);
  9387. flush_buffers(gen);
  9388. for (j = 0; j < gen->chans; j++)
  9389. memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t));
  9390. gen->data_start = samp;
  9391. gen->data_end = samp + clm_file_buffer_size - 1;
  9392. gen->obufs[chan][0] += val;
  9393. gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */
  9394. }
  9395. if (samp > gen->out_end)
  9396. gen->out_end = samp;
  9397. return(val);
  9398. }
  9399. static void mus_out_chans_to_file(rdout *gen, mus_long_t samp, int chans, mus_float_t *vals)
  9400. {
  9401. int i;
  9402. if ((samp <= gen->data_end) &&
  9403. (samp >= gen->data_start))
  9404. {
  9405. mus_long_t pos;
  9406. pos = samp - gen->data_start;
  9407. for (i = 0; i < chans; i++)
  9408. gen->obufs[i][pos] += vals[i];
  9409. }
  9410. else
  9411. {
  9412. int j;
  9413. if (samp < 0) return;
  9414. flush_buffers(gen);
  9415. for (j = 0; j < gen->chans; j++)
  9416. memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t));
  9417. gen->data_start = samp;
  9418. gen->data_end = samp + clm_file_buffer_size - 1;
  9419. for (i = 0; i < chans; i++)
  9420. gen->obufs[i][0] += vals[i];
  9421. gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */
  9422. }
  9423. if (samp > gen->out_end)
  9424. gen->out_end = samp;
  9425. }
  9426. static mus_float_t mus_outa_to_file(mus_any *ptr, mus_long_t samp, mus_float_t val)
  9427. {
  9428. rdout *gen = (rdout *)ptr;
  9429. if (!ptr) return(val);
  9430. if ((!(gen->obuf0)) ||
  9431. (!(gen->obufs)))
  9432. return(val);
  9433. if ((samp <= gen->data_end) &&
  9434. (samp >= gen->data_start))
  9435. gen->obuf0[samp - gen->data_start] += val;
  9436. else
  9437. {
  9438. int j;
  9439. if (samp < 0) return(val);
  9440. flush_buffers(gen);
  9441. for (j = 0; j < gen->chans; j++)
  9442. memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t));
  9443. gen->data_start = samp;
  9444. gen->data_end = samp + clm_file_buffer_size - 1;
  9445. gen->obuf0[0] += val;
  9446. gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */
  9447. }
  9448. if (samp > gen->out_end)
  9449. gen->out_end = samp;
  9450. return(val);
  9451. }
  9452. static mus_float_t mus_outb_to_file(mus_any *ptr, mus_long_t samp, mus_float_t val)
  9453. {
  9454. rdout *gen = (rdout *)ptr;
  9455. if (!ptr) return(val);
  9456. if ((!(gen->obuf1)) ||
  9457. (!(gen->obufs)))
  9458. return(val);
  9459. if ((samp <= gen->data_end) &&
  9460. (samp >= gen->data_start))
  9461. gen->obuf1[samp - gen->data_start] += val;
  9462. else
  9463. {
  9464. int j;
  9465. if (samp < 0) return(val);
  9466. flush_buffers(gen);
  9467. for (j = 0; j < gen->chans; j++)
  9468. memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t));
  9469. gen->data_start = samp;
  9470. gen->data_end = samp + clm_file_buffer_size - 1;
  9471. gen->obuf1[0] += val;
  9472. gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */
  9473. }
  9474. if (samp > gen->out_end)
  9475. gen->out_end = samp;
  9476. return(val);
  9477. }
  9478. static int sample_to_file_end(mus_any *ptr)
  9479. {
  9480. rdout *gen = (rdout *)ptr;
  9481. if ((gen) && (gen->obufs))
  9482. {
  9483. if (gen->chans > 0)
  9484. {
  9485. int i;
  9486. flush_buffers(gen); /* this forces the error handling stuff, unlike in free reader case */
  9487. for (i = 0; i < gen->chans; i++)
  9488. if (gen->obufs[i])
  9489. free(gen->obufs[i]);
  9490. }
  9491. free(gen->obufs);
  9492. gen->obufs = NULL;
  9493. gen->obuf0 = NULL;
  9494. gen->obuf1 = NULL;
  9495. }
  9496. return(0);
  9497. }
  9498. bool mus_is_sample_to_file(mus_any *ptr)
  9499. {
  9500. return((ptr) &&
  9501. (ptr->core->type == MUS_SAMPLE_TO_FILE));
  9502. }
  9503. static mus_any *mus_make_sample_to_file_with_comment_1(const char *filename, int out_chans,
  9504. mus_sample_t samp_type, mus_header_t head_type, const char *comment, bool reopen)
  9505. {
  9506. if (filename == NULL)
  9507. mus_error(MUS_NO_FILE_NAME_PROVIDED, S_make_sample_to_file " requires a file name");
  9508. else
  9509. {
  9510. int fd;
  9511. if (out_chans <= 0)
  9512. return(NULL);
  9513. if (reopen)
  9514. fd = mus_sound_reopen_output(filename, out_chans, samp_type, head_type, mus_sound_data_location(filename));
  9515. else fd = mus_sound_open_output(filename, (int)sampling_rate, out_chans, samp_type, head_type, comment);
  9516. if (fd == -1)
  9517. mus_error(MUS_CANT_OPEN_FILE,
  9518. S_make_sample_to_file ": open(%s) -> %s",
  9519. filename, STRERROR(errno));
  9520. else
  9521. {
  9522. rdout *gen;
  9523. int i;
  9524. gen = (rdout *)calloc(1, sizeof(rdout));
  9525. gen->core = &SAMPLE_TO_FILE_CLASS;
  9526. gen->file_name = (char *)calloc(strlen(filename) + 1, sizeof(char));
  9527. strcpy(gen->file_name, filename);
  9528. gen->data_start = 0;
  9529. gen->data_end = clm_file_buffer_size - 1;
  9530. gen->out_end = 0;
  9531. gen->chans = out_chans;
  9532. gen->output_sample_type = samp_type;
  9533. gen->output_header_type = head_type;
  9534. gen->obufs = (mus_float_t **)malloc(gen->chans * sizeof(mus_float_t *));
  9535. for (i = 0; i < gen->chans; i++)
  9536. gen->obufs[i] = (mus_float_t *)calloc(clm_file_buffer_size, sizeof(mus_float_t));
  9537. gen->obuf0 = gen->obufs[0];
  9538. if (out_chans > 1)
  9539. gen->obuf1 = gen->obufs[1];
  9540. else gen->obuf1 = NULL;
  9541. /* clear previous, if any */
  9542. if (mus_file_close(fd) != 0)
  9543. mus_error(MUS_CANT_CLOSE_FILE,
  9544. S_make_sample_to_file ": close(%d, %s) -> %s",
  9545. fd, gen->file_name, STRERROR(errno));
  9546. return((mus_any *)gen);
  9547. }
  9548. }
  9549. return(NULL);
  9550. }
  9551. mus_any *mus_continue_sample_to_file(const char *filename)
  9552. {
  9553. return(mus_make_sample_to_file_with_comment_1(filename,
  9554. mus_sound_chans(filename),
  9555. mus_sound_sample_type(filename),
  9556. mus_sound_header_type(filename),
  9557. NULL,
  9558. true));
  9559. }
  9560. mus_any *mus_make_sample_to_file_with_comment(const char *filename, int out_chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment)
  9561. {
  9562. return(mus_make_sample_to_file_with_comment_1(filename, out_chans, samp_type, head_type, comment, false));
  9563. }
  9564. mus_float_t mus_sample_to_file(mus_any *fd, mus_long_t samp, int chan, mus_float_t val)
  9565. {
  9566. /* return(mus_write_sample(ptr, samp, chan, val)); */
  9567. if ((fd) &&
  9568. ((fd->core)->write_sample))
  9569. return(((*(fd->core)->write_sample))(fd, samp, chan, val));
  9570. mus_error(MUS_NO_SAMPLE_OUTPUT,
  9571. S_sample_to_file ": can't find %s's sample output function",
  9572. mus_name(fd));
  9573. return(val);
  9574. }
  9575. int mus_close_file(mus_any *ptr)
  9576. {
  9577. rdout *gen = (rdout *)ptr;
  9578. if ((mus_is_output(ptr)) && (gen->obufs)) sample_to_file_end(ptr);
  9579. return(0);
  9580. }
  9581. /* ---------------- out-any ---------------- */
  9582. mus_float_t mus_out_any(mus_long_t samp, mus_float_t val, int chan, mus_any *IO)
  9583. {
  9584. if ((IO) &&
  9585. (samp >= 0))
  9586. {
  9587. if ((IO->core)->write_sample)
  9588. return(((*(IO->core)->write_sample))(IO, samp, chan, val));
  9589. mus_error(MUS_NO_SAMPLE_OUTPUT,
  9590. "can't find %s's sample output function",
  9591. mus_name(IO));
  9592. }
  9593. return(val);
  9594. }
  9595. mus_float_t mus_safe_out_any_to_file(mus_long_t samp, mus_float_t val, int chan, mus_any *IO)
  9596. {
  9597. rdout *gen = (rdout *)IO;
  9598. if (chan >= gen->chans) /* checking for (val == 0.0) here appears to make no difference overall */
  9599. return(val);
  9600. /* does this need to check obufs? */
  9601. if ((samp <= gen->data_end) &&
  9602. (samp >= gen->data_start))
  9603. {
  9604. gen->obufs[chan][samp - gen->data_start] += val;
  9605. if (samp > gen->out_end)
  9606. gen->out_end = samp;
  9607. }
  9608. else
  9609. {
  9610. int j;
  9611. if (samp < 0) return(val);
  9612. flush_buffers(gen);
  9613. for (j = 0; j < gen->chans; j++)
  9614. memset((void *)(gen->obufs[j]), 0, clm_file_buffer_size * sizeof(mus_float_t));
  9615. gen->data_start = samp;
  9616. gen->data_end = samp + clm_file_buffer_size - 1;
  9617. gen->obufs[chan][0] += val;
  9618. gen->out_end = samp; /* this resets the current notion of where in the buffer the new data ends */
  9619. }
  9620. return(val);
  9621. }
  9622. bool mus_out_any_is_safe(mus_any *IO)
  9623. {
  9624. rdout *gen = (rdout *)IO;
  9625. return((gen) &&
  9626. (gen->obufs) &&
  9627. (gen->core->write_sample == mus_out_any_to_file));
  9628. }
  9629. /* ---------------- frample->file ---------------- */
  9630. static char *describe_frample_to_file(mus_any *ptr)
  9631. {
  9632. rdout *gen = (rdout *)ptr;
  9633. char *describe_buffer;
  9634. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  9635. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s %s",
  9636. mus_name(ptr),
  9637. gen->file_name);
  9638. return(describe_buffer);
  9639. }
  9640. static mus_float_t run_frample_to_file(mus_any *ptr, mus_float_t arg1, mus_float_t arg2)
  9641. {
  9642. mus_error(MUS_NO_RUN, "no run method for frample->file");
  9643. return(0.0);
  9644. }
  9645. static mus_any_class FRAMPLE_TO_FILE_CLASS = {
  9646. MUS_FRAMPLE_TO_FILE,
  9647. (char *)S_frample_to_file,
  9648. &free_sample_to_file,
  9649. &describe_frample_to_file,
  9650. &sample_to_file_equalp,
  9651. 0, 0,
  9652. &bufferlen, &set_bufferlen,
  9653. 0, 0, 0, 0,
  9654. &fallback_scaler, 0,
  9655. 0, 0,
  9656. &run_frample_to_file,
  9657. MUS_OUTPUT,
  9658. NULL,
  9659. &sample_to_file_channels,
  9660. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  9661. 0,
  9662. &mus_out_any_to_file,
  9663. &sample_to_file_file_name,
  9664. &sample_to_file_end,
  9665. 0, 0, 0,
  9666. 0, 0, 0, 0,
  9667. &no_reset,
  9668. 0, &rdout_copy
  9669. };
  9670. mus_any *mus_make_frample_to_file_with_comment(const char *filename, int chans, mus_sample_t samp_type, mus_header_t head_type, const char *comment)
  9671. {
  9672. rdout *gen = NULL;
  9673. gen = (rdout *)mus_make_sample_to_file_with_comment(filename, chans, samp_type, head_type, comment);
  9674. if (gen) gen->core = &FRAMPLE_TO_FILE_CLASS;
  9675. return((mus_any *)gen);
  9676. }
  9677. bool mus_is_frample_to_file(mus_any *ptr)
  9678. {
  9679. return((ptr) &&
  9680. (ptr->core->type == MUS_FRAMPLE_TO_FILE));
  9681. }
  9682. mus_float_t *mus_frample_to_file(mus_any *ptr, mus_long_t samp, mus_float_t *data)
  9683. {
  9684. rdout *gen = (rdout *)ptr;
  9685. if (!gen) return(data);
  9686. if (gen->chans == 1)
  9687. mus_outa_to_file(ptr, samp, data[0]);
  9688. else
  9689. {
  9690. if (gen->chans == 2)
  9691. {
  9692. mus_outa_to_file(ptr, samp, data[0]);
  9693. mus_outb_to_file(ptr, samp, data[1]);
  9694. }
  9695. else mus_out_chans_to_file(gen, samp, gen->chans, data);
  9696. }
  9697. return(data);
  9698. }
  9699. mus_any *mus_continue_frample_to_file(const char *filename)
  9700. {
  9701. rdout *gen = NULL;
  9702. gen = (rdout *)mus_continue_sample_to_file(filename);
  9703. if (gen) gen->core = &FRAMPLE_TO_FILE_CLASS;
  9704. return((mus_any *)gen);
  9705. }
  9706. mus_float_t *mus_frample_to_frample(mus_float_t *matrix, int mx_chans, mus_float_t *in_samps, int in_chans, mus_float_t *out_samps, int out_chans)
  9707. {
  9708. /* in->out conceptually, so left index is in_chan, it (j below) steps by out_chans */
  9709. int i, j, offset;
  9710. if (mx_chans < out_chans) out_chans = mx_chans;
  9711. if (mx_chans < in_chans) in_chans = mx_chans;
  9712. for (i = 0; i < out_chans; i++)
  9713. {
  9714. out_samps[i] = in_samps[0] * matrix[i];
  9715. for (j = 1, offset = mx_chans; j < in_chans; j++, offset += mx_chans)
  9716. out_samps[i] += in_samps[j] * matrix[offset + i];
  9717. }
  9718. return(out_samps);
  9719. }
  9720. /* ---------------- locsig ---------------- */
  9721. typedef struct {
  9722. mus_any_class *core;
  9723. mus_any *outn_writer;
  9724. mus_any *revn_writer;
  9725. mus_float_t *outf, *revf;
  9726. mus_float_t *outn;
  9727. mus_float_t *revn;
  9728. int chans, rev_chans;
  9729. mus_interp_t type;
  9730. mus_float_t reverb;
  9731. bool safe_output;
  9732. void *closure;
  9733. void (*locsig_func)(mus_any *ptr, mus_long_t loc, mus_float_t val);
  9734. void (*detour)(mus_any *ptr, mus_long_t loc);
  9735. } locs;
  9736. static bool locsig_equalp(mus_any *p1, mus_any *p2)
  9737. {
  9738. locs *g1 = (locs *)p1;
  9739. locs *g2 = (locs *)p2;
  9740. if (p1 == p2) return(true);
  9741. return((g1) && (g2) &&
  9742. (g1->core->type == g2->core->type) &&
  9743. (g1->chans == g2->chans) &&
  9744. (clm_arrays_are_equal(g1->outn, g2->outn, g1->chans)) &&
  9745. (((bool)(g1->revn != NULL)) == ((bool)(g2->revn != NULL))) &&
  9746. ((!(g1->revn)) || (clm_arrays_are_equal(g1->revn, g2->revn, g1->rev_chans))));
  9747. }
  9748. static char *describe_locsig(mus_any *ptr)
  9749. {
  9750. char *str;
  9751. int i, lim = 16;
  9752. locs *gen = (locs *)ptr;
  9753. char *describe_buffer;
  9754. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  9755. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s chans %d, outn: [",
  9756. mus_name(ptr),
  9757. gen->chans);
  9758. str = (char *)malloc(STR_SIZE * sizeof(char));
  9759. if (gen->outn)
  9760. {
  9761. if (gen->chans - 1 < lim) lim = gen->chans - 1;
  9762. for (i = 0; i < lim; i++)
  9763. {
  9764. snprintf(str, STR_SIZE, "%.3f ", gen->outn[i]);
  9765. if ((strlen(describe_buffer) + strlen(str)) < (DESCRIBE_BUFFER_SIZE - 16))
  9766. strcat(describe_buffer, str);
  9767. else break;
  9768. }
  9769. if (gen->chans - 1 > lim) strcat(describe_buffer, "...");
  9770. snprintf(str, STR_SIZE, "%.3f]", gen->outn[gen->chans - 1]);
  9771. strcat(describe_buffer, str);
  9772. }
  9773. else
  9774. {
  9775. strcat(describe_buffer, "nil!]");
  9776. }
  9777. if ((gen->rev_chans > 0) && (gen->revn))
  9778. {
  9779. strcat(describe_buffer, ", revn: [");
  9780. lim = 16;
  9781. if (gen->rev_chans - 1 < lim) lim = gen->rev_chans - 1;
  9782. for (i = 0; i < lim; i++)
  9783. {
  9784. snprintf(str, STR_SIZE, "%.3f ", gen->revn[i]);
  9785. if ((strlen(describe_buffer) + strlen(str)) < (DESCRIBE_BUFFER_SIZE - 16))
  9786. strcat(describe_buffer, str);
  9787. else break;
  9788. }
  9789. if (gen->rev_chans - 1 > lim) strcat(describe_buffer, "...");
  9790. snprintf(str, STR_SIZE, "%.3f]", gen->revn[gen->rev_chans - 1]);
  9791. strcat(describe_buffer, str);
  9792. }
  9793. snprintf(str, STR_SIZE, ", interp: %s", interp_type_to_string(gen->type));
  9794. strcat(describe_buffer, str);
  9795. free(str);
  9796. return(describe_buffer);
  9797. }
  9798. static void free_locsig(mus_any *p)
  9799. {
  9800. locs *ptr = (locs *)p;
  9801. if (ptr->outn)
  9802. {
  9803. free(ptr->outn);
  9804. ptr->outn = NULL;
  9805. }
  9806. if (ptr->revn)
  9807. {
  9808. free(ptr->revn);
  9809. ptr->revn = NULL;
  9810. }
  9811. if (ptr->outf) free(ptr->outf);
  9812. ptr->outf = NULL;
  9813. if (ptr->revf) free(ptr->revf);
  9814. ptr->revf = NULL;
  9815. ptr->outn_writer = NULL;
  9816. ptr->revn_writer = NULL;
  9817. ptr->chans = 0;
  9818. ptr->rev_chans = 0;
  9819. free(ptr);
  9820. }
  9821. static mus_any *locs_copy(mus_any *ptr)
  9822. {
  9823. locs *g, *p;
  9824. int bytes;
  9825. p = (locs *)ptr;
  9826. g = (locs *)malloc(sizeof(locs));
  9827. memcpy((void *)g, (void *)ptr, sizeof(locs));
  9828. bytes = g->chans * sizeof(mus_float_t);
  9829. if (p->outn)
  9830. {
  9831. g->outn = (mus_float_t *)malloc(bytes);
  9832. memcpy((void *)(g->outn), (void *)(p->outn), bytes);
  9833. }
  9834. if (p->outf)
  9835. {
  9836. g->outf = (mus_float_t *)malloc(bytes);
  9837. memcpy((void *)(g->outf), (void *)(p->outf), bytes);
  9838. }
  9839. bytes = g->rev_chans * sizeof(mus_float_t);
  9840. if (p->revn)
  9841. {
  9842. g->revn = (mus_float_t *)malloc(bytes);
  9843. memcpy((void *)(g->revn), (void *)(p->revn), bytes);
  9844. }
  9845. if (p->revf)
  9846. {
  9847. g->revf = (mus_float_t *)malloc(bytes);
  9848. memcpy((void *)(g->revf), (void *)(p->revf), bytes);
  9849. }
  9850. return((mus_any *)g);
  9851. }
  9852. static mus_long_t locsig_length(mus_any *ptr) {return(((locs *)ptr)->chans);}
  9853. static int locsig_channels(mus_any *ptr) {return(((locs *)ptr)->chans);}
  9854. static mus_float_t *locsig_data(mus_any *ptr) {return(((locs *)ptr)->outn);}
  9855. static mus_float_t *locsig_xcoeffs(mus_any *ptr) {return(((locs *)ptr)->revn);}
  9856. mus_float_t *mus_locsig_outf(mus_any *ptr) {return(((locs *)ptr)->outf);} /* clm2xen.c */
  9857. mus_float_t *mus_locsig_revf(mus_any *ptr) {return(((locs *)ptr)->revf);}
  9858. void *mus_locsig_closure(mus_any *ptr) {return(((locs *)ptr)->closure);}
  9859. static void *locsig_set_closure(mus_any *ptr, void *e) {((locs *)ptr)->closure = e; return(e);}
  9860. void mus_locsig_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val))
  9861. {
  9862. locs *gen = (locs *)ptr;
  9863. gen->detour = detour;
  9864. }
  9865. static void locsig_reset(mus_any *ptr)
  9866. {
  9867. locs *gen = (locs *)ptr;
  9868. if (gen->outn) memset((void *)(gen->outn), 0, gen->chans * sizeof(mus_float_t));
  9869. if (gen->revn) memset((void *)(gen->revn), 0, gen->rev_chans * sizeof(mus_float_t));
  9870. }
  9871. static mus_float_t locsig_xcoeff(mus_any *ptr, int index)
  9872. {
  9873. locs *gen = (locs *)ptr;
  9874. if (gen->revn)
  9875. return(gen->revn[index]);
  9876. return(0.0);
  9877. }
  9878. static mus_float_t locsig_set_xcoeff(mus_any *ptr, int index, mus_float_t val)
  9879. {
  9880. locs *gen = (locs *)ptr;
  9881. if (gen->revn)
  9882. gen->revn[index] = val;
  9883. return(val);
  9884. }
  9885. static mus_any *locsig_warned = NULL;
  9886. /* these locsig error messages are a pain -- using the output pointer in the wan hope that
  9887. * subsequent runs will use a different output generator.
  9888. */
  9889. mus_float_t mus_locsig_ref(mus_any *ptr, int chan)
  9890. {
  9891. locs *gen = (locs *)ptr;
  9892. if ((ptr) && (mus_is_locsig(ptr)))
  9893. {
  9894. if ((chan >= 0) &&
  9895. (chan < gen->chans))
  9896. return(gen->outn[chan]);
  9897. else
  9898. {
  9899. if (locsig_warned != gen->outn_writer)
  9900. {
  9901. mus_error(MUS_NO_SUCH_CHANNEL,
  9902. S_locsig_ref ": chan %d >= %d",
  9903. chan, gen->chans);
  9904. locsig_warned = gen->outn_writer;
  9905. }
  9906. }
  9907. }
  9908. return(0.0);
  9909. }
  9910. mus_float_t mus_locsig_set(mus_any *ptr, int chan, mus_float_t val)
  9911. {
  9912. locs *gen = (locs *)ptr;
  9913. if ((ptr) && (mus_is_locsig(ptr)))
  9914. {
  9915. if ((chan >= 0) &&
  9916. (chan < gen->chans))
  9917. gen->outn[chan] = val;
  9918. else
  9919. {
  9920. if (locsig_warned != gen->outn_writer)
  9921. {
  9922. mus_error(MUS_NO_SUCH_CHANNEL,
  9923. S_locsig_set ": chan %d >= %d",
  9924. chan, gen->chans);
  9925. locsig_warned = gen->outn_writer;
  9926. }
  9927. }
  9928. }
  9929. return(val);
  9930. }
  9931. mus_float_t mus_locsig_reverb_ref(mus_any *ptr, int chan)
  9932. {
  9933. locs *gen = (locs *)ptr;
  9934. if ((ptr) && (mus_is_locsig(ptr)))
  9935. {
  9936. if ((chan >= 0) &&
  9937. (chan < gen->rev_chans))
  9938. return(gen->revn[chan]);
  9939. else
  9940. {
  9941. if (locsig_warned != gen->outn_writer)
  9942. {
  9943. mus_error(MUS_NO_SUCH_CHANNEL,
  9944. S_locsig_reverb_ref ": chan %d, but this locsig has %d reverb chans",
  9945. chan, gen->rev_chans);
  9946. locsig_warned = gen->outn_writer;
  9947. }
  9948. }
  9949. }
  9950. return(0.0);
  9951. }
  9952. mus_float_t mus_locsig_reverb_set(mus_any *ptr, int chan, mus_float_t val)
  9953. {
  9954. locs *gen = (locs *)ptr;
  9955. if ((ptr) && (mus_is_locsig(ptr)))
  9956. {
  9957. if ((chan >= 0) &&
  9958. (chan < gen->rev_chans))
  9959. gen->revn[chan] = val;
  9960. else
  9961. {
  9962. if (locsig_warned != gen->outn_writer)
  9963. {
  9964. mus_error(MUS_NO_SUCH_CHANNEL,
  9965. S_locsig_reverb_set ": chan %d >= %d",
  9966. chan, gen->rev_chans);
  9967. locsig_warned = gen->outn_writer;
  9968. }
  9969. }
  9970. }
  9971. return(val);
  9972. }
  9973. static mus_float_t run_locsig(mus_any *ptr, mus_float_t arg1, mus_float_t arg2)
  9974. {
  9975. mus_locsig(ptr, (mus_long_t)arg1, arg2);
  9976. return(arg2);
  9977. }
  9978. static mus_any_class LOCSIG_CLASS = {
  9979. MUS_LOCSIG,
  9980. (char *)S_locsig,
  9981. &free_locsig,
  9982. &describe_locsig,
  9983. &locsig_equalp,
  9984. &locsig_data, 0,
  9985. &locsig_length,
  9986. 0,
  9987. 0, 0, 0, 0,
  9988. 0, 0,
  9989. 0, 0,
  9990. &run_locsig,
  9991. MUS_OUTPUT,
  9992. &mus_locsig_closure,
  9993. &locsig_channels,
  9994. 0, 0, 0, 0,
  9995. &locsig_xcoeff, &locsig_set_xcoeff,
  9996. 0, 0, 0, 0,
  9997. 0, 0, 0, 0, 0, 0, 0,
  9998. 0, 0,
  9999. &locsig_xcoeffs, 0,
  10000. &locsig_reset,
  10001. &locsig_set_closure, /* the method name is set_environ (clm2xen.c) */
  10002. &locs_copy
  10003. };
  10004. bool mus_is_locsig(mus_any *ptr)
  10005. {
  10006. return((ptr) &&
  10007. (ptr->core->type == MUS_LOCSIG));
  10008. }
  10009. static void mus_locsig_fill(mus_float_t *arr, int chans, mus_float_t degree, mus_float_t scaler, mus_interp_t type)
  10010. {
  10011. if (chans == 1)
  10012. arr[0] = scaler;
  10013. else
  10014. {
  10015. mus_float_t deg, pos, frac, degs_per_chan;
  10016. int left, right;
  10017. /* this used to check for degree < 0.0 first, but as Michael Klingbeil noticed, that
  10018. * means that in the stereo case, the location can jump to 90 => click.
  10019. */
  10020. if (chans == 2)
  10021. {
  10022. /* there's no notion of a circle of speakers here, so we don't have to equate, for example, -90 and 270 */
  10023. if (degree > 90.0)
  10024. deg = 90.0;
  10025. else
  10026. {
  10027. if (degree < 0.0)
  10028. deg = 0.0;
  10029. else deg = degree;
  10030. }
  10031. degs_per_chan = 90.0;
  10032. }
  10033. else
  10034. {
  10035. deg = fmod(degree, 360.0);
  10036. if (deg < 0.0)
  10037. {
  10038. /* -0.0 is causing trouble when mus_float_t == float */
  10039. if (deg < -0.0000001)
  10040. deg += 360.0; /* C's fmod can return negative results when modulus is positive */
  10041. else deg = 0.0;
  10042. }
  10043. degs_per_chan = 360.0 / chans;
  10044. }
  10045. pos = deg / degs_per_chan;
  10046. left = (int)pos; /* floor(pos) */
  10047. right = left + 1;
  10048. if (right >= chans) right = 0;
  10049. frac = pos - left;
  10050. if (type == MUS_INTERP_LINEAR)
  10051. {
  10052. arr[left] = scaler * (1.0 - frac);
  10053. arr[right] = scaler * frac;
  10054. }
  10055. else
  10056. {
  10057. mus_float_t ldeg, c, s;
  10058. ldeg = M_PI_2 * (0.5 - frac);
  10059. scaler *= sqrt(2.0) / 2.0;
  10060. c = cos(ldeg);
  10061. s = sin(ldeg);
  10062. arr[left] = scaler * (c + s);
  10063. arr[right] = scaler * (c - s);
  10064. }
  10065. }
  10066. }
  10067. static void mus_locsig_mono_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10068. {
  10069. locs *gen = (locs *)ptr;
  10070. mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]);
  10071. }
  10072. static void mus_locsig_mono(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10073. {
  10074. locs *gen = (locs *)ptr;
  10075. mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]);
  10076. mus_outa_to_file(gen->revn_writer, loc, val * gen->revn[0]);
  10077. }
  10078. static void mus_locsig_stereo_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10079. {
  10080. locs *gen = (locs *)ptr;
  10081. mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]);
  10082. mus_outb_to_file(gen->outn_writer, loc, val * gen->outn[1]);
  10083. }
  10084. static void mus_locsig_stereo(mus_any *ptr, mus_long_t loc, mus_float_t val) /* but mono rev */
  10085. {
  10086. locs *gen = (locs *)ptr;
  10087. mus_outa_to_file(gen->outn_writer, loc, val * gen->outn[0]);
  10088. mus_outb_to_file(gen->outn_writer, loc, val * gen->outn[1]);
  10089. mus_outa_to_file(gen->revn_writer, loc, val * gen->revn[0]);
  10090. }
  10091. static void mus_locsig_any(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10092. {
  10093. int i;
  10094. locs *gen = (locs *)ptr;
  10095. rdout *writer = (rdout *)(gen->outn_writer);
  10096. for (i = 0; i < gen->chans; i++)
  10097. {
  10098. gen->outf[i] = val * gen->outn[i];
  10099. if (writer)
  10100. mus_out_any_to_file((mus_any *)writer, loc, i, gen->outf[i]);
  10101. }
  10102. writer = (rdout *)(gen->revn_writer);
  10103. for (i = 0; i < gen->rev_chans; i++)
  10104. {
  10105. gen->revf[i] = val * gen->revn[i];
  10106. if (writer)
  10107. mus_out_any_to_file((mus_any *)writer, loc, i, gen->revf[i]);
  10108. }
  10109. }
  10110. static void mus_locsig_safe_mono_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10111. {
  10112. /* here we know in each safe case that obufs fits loc chans and the output gen is ok */
  10113. locs *gen = (locs *)ptr;
  10114. rdout *writer = (rdout *)(gen->outn_writer);
  10115. if ((loc <= writer->data_end) &&
  10116. (loc >= writer->data_start))
  10117. {
  10118. writer->obufs[0][loc - writer->data_start] += (val * gen->outn[0]);
  10119. if (loc > writer->out_end)
  10120. writer->out_end = loc;
  10121. }
  10122. else mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]);
  10123. }
  10124. static void mus_locsig_safe_mono(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10125. {
  10126. locs *gen = (locs *)ptr;
  10127. rdout *writer = (rdout *)(gen->outn_writer);
  10128. if ((loc <= writer->data_end) &&
  10129. (loc >= writer->data_start))
  10130. {
  10131. writer->obufs[0][loc - writer->data_start] += (val * gen->outn[0]);
  10132. if (loc > writer->out_end)
  10133. writer->out_end = loc;
  10134. }
  10135. else mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]);
  10136. writer = (rdout *)(gen->revn_writer);
  10137. if ((loc <= writer->data_end) &&
  10138. (loc >= writer->data_start))
  10139. {
  10140. writer->obufs[0][loc - writer->data_start] += (val * gen->revn[0]);
  10141. if (loc > writer->out_end)
  10142. writer->out_end = loc;
  10143. }
  10144. else mus_outa_to_file((mus_any *)writer, loc, val * gen->revn[0]);
  10145. }
  10146. static void mus_locsig_safe_stereo_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10147. {
  10148. locs *gen = (locs *)ptr;
  10149. rdout *writer = (rdout *)(gen->outn_writer);
  10150. if ((loc <= writer->data_end) &&
  10151. (loc >= writer->data_start))
  10152. {
  10153. mus_long_t pos;
  10154. pos = loc - writer->data_start;
  10155. writer->obufs[0][pos] += (val * gen->outn[0]);
  10156. writer->obufs[1][pos] += (val * gen->outn[1]);
  10157. if (loc > writer->out_end)
  10158. writer->out_end = loc;
  10159. }
  10160. else
  10161. {
  10162. mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]);
  10163. mus_outb_to_file((mus_any *)writer, loc, val * gen->outn[1]);
  10164. }
  10165. }
  10166. static void mus_locsig_safe_stereo(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10167. {
  10168. locs *gen = (locs *)ptr;
  10169. rdout *writer = (rdout *)(gen->outn_writer);
  10170. if ((loc <= writer->data_end) &&
  10171. (loc >= writer->data_start))
  10172. {
  10173. mus_long_t pos;
  10174. pos = loc - writer->data_start;
  10175. writer->obufs[0][pos] += (val * gen->outn[0]);
  10176. writer->obufs[1][pos] += (val * gen->outn[1]);
  10177. if (loc > writer->out_end)
  10178. writer->out_end = loc;
  10179. }
  10180. else
  10181. {
  10182. mus_outa_to_file((mus_any *)writer, loc, val * gen->outn[0]);
  10183. mus_outb_to_file((mus_any *)writer, loc, val * gen->outn[1]);
  10184. }
  10185. writer = (rdout *)(gen->revn_writer);
  10186. if ((loc <= writer->data_end) &&
  10187. (loc >= writer->data_start))
  10188. {
  10189. writer->obufs[0][loc - writer->data_start] += (val * gen->revn[0]);
  10190. if (loc > writer->out_end)
  10191. writer->out_end = loc;
  10192. }
  10193. else mus_outa_to_file((mus_any *)writer, loc, val * gen->revn[0]);
  10194. }
  10195. static void mus_locsig_detour(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10196. {
  10197. /* here we let the closure data decide what to do with the output */
  10198. locs *gen = (locs *)ptr;
  10199. if (gen->detour)
  10200. {
  10201. int i;
  10202. for (i = 0; i < gen->chans; i++)
  10203. gen->outf[i] = val * gen->outn[i];
  10204. for (i = 0; i < gen->rev_chans; i++)
  10205. gen->revf[i] = val * gen->revn[i];
  10206. (*(gen->detour))(ptr, loc);
  10207. }
  10208. }
  10209. static void mus_locsig_any_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10210. {
  10211. int i;
  10212. locs *gen = (locs *)ptr;
  10213. rdout *writer = (rdout *)(gen->outn_writer);
  10214. for (i = 0; i < gen->chans; i++)
  10215. {
  10216. gen->outf[i] = val * gen->outn[i];
  10217. if (writer)
  10218. mus_out_any_to_file((mus_any *)writer, loc, i, gen->outf[i]);
  10219. }
  10220. }
  10221. static void mus_locsig_safe_any_no_reverb(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10222. {
  10223. int i;
  10224. locs *gen = (locs *)ptr;
  10225. rdout *writer = (rdout *)(gen->outn_writer);
  10226. if ((loc <= writer->data_end) &&
  10227. (loc >= writer->data_start))
  10228. {
  10229. mus_long_t pos;
  10230. pos = loc - writer->data_start;
  10231. for (i = 0; i < gen->chans; i++)
  10232. writer->obufs[i][pos] += (val * gen->outn[i]);
  10233. if (loc > writer->out_end)
  10234. writer->out_end = loc;
  10235. }
  10236. else
  10237. {
  10238. for (i = 0; i < gen->chans; i++)
  10239. mus_safe_out_any_to_file(loc, val * gen->outn[i], i, (mus_any *)writer);
  10240. }
  10241. }
  10242. static void mus_locsig_safe_any(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10243. {
  10244. int i;
  10245. locs *gen = (locs *)ptr;
  10246. rdout *writer = (rdout *)(gen->outn_writer);
  10247. if ((loc <= writer->data_end) &&
  10248. (loc >= writer->data_start))
  10249. {
  10250. mus_long_t pos;
  10251. pos = loc - writer->data_start;
  10252. for (i = 0; i < gen->chans; i++)
  10253. writer->obufs[i][pos] += (val * gen->outn[i]);
  10254. if (loc > writer->out_end)
  10255. writer->out_end = loc;
  10256. }
  10257. else
  10258. {
  10259. for (i = 0; i < gen->chans; i++)
  10260. mus_safe_out_any_to_file(loc, val * gen->outn[i], i, (mus_any *)writer);
  10261. }
  10262. writer = (rdout *)(gen->revn_writer);
  10263. if ((loc <= writer->data_end) &&
  10264. (loc >= writer->data_start))
  10265. {
  10266. mus_long_t pos;
  10267. pos = loc - writer->data_start;
  10268. for (i = 0; i < gen->rev_chans; i++)
  10269. writer->obufs[i][pos] += (val * gen->revn[i]);
  10270. if (loc > writer->out_end)
  10271. writer->out_end = loc;
  10272. }
  10273. else
  10274. {
  10275. for (i = 0; i < gen->rev_chans; i++)
  10276. mus_safe_out_any_to_file(loc, val * gen->revn[i], i, (mus_any *)writer);
  10277. }
  10278. }
  10279. mus_any *mus_make_locsig(mus_float_t degree, mus_float_t distance, mus_float_t reverb,
  10280. int chans, mus_any *output, /* direct signal output */
  10281. int rev_chans, mus_any *revput, /* reverb output */
  10282. mus_interp_t type)
  10283. {
  10284. locs *gen;
  10285. mus_float_t dist;
  10286. if (chans <= 0)
  10287. {
  10288. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_locsig ": chans: %d", chans);
  10289. return(NULL);
  10290. }
  10291. if (isnan(degree))
  10292. {
  10293. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_locsig ": degree: %f", degree);
  10294. return(NULL);
  10295. }
  10296. gen = (locs *)calloc(1, sizeof(locs));
  10297. gen->core = &LOCSIG_CLASS;
  10298. gen->outf = (mus_float_t *)calloc(chans, sizeof(mus_float_t));
  10299. gen->type = type;
  10300. gen->reverb = reverb;
  10301. gen->safe_output = false;
  10302. if (distance > 1.0)
  10303. dist = 1.0 / distance;
  10304. else dist = 1.0;
  10305. if (mus_is_output(output))
  10306. gen->outn_writer = output;
  10307. gen->chans = chans;
  10308. gen->outn = (mus_float_t *)calloc(gen->chans, sizeof(mus_float_t));
  10309. mus_locsig_fill(gen->outn, gen->chans, degree, dist, type);
  10310. if (mus_is_output(revput))
  10311. gen->revn_writer = revput;
  10312. gen->rev_chans = rev_chans;
  10313. if (gen->rev_chans > 0)
  10314. {
  10315. gen->revn = (mus_float_t *)calloc(gen->rev_chans, sizeof(mus_float_t));
  10316. gen->revf = (mus_float_t *)calloc(gen->rev_chans, sizeof(mus_float_t));
  10317. mus_locsig_fill(gen->revn, gen->rev_chans, degree, (reverb * sqrt(dist)), type);
  10318. }
  10319. /* now choose the output function based on chans, and reverb
  10320. */
  10321. if ((output == NULL) && (revput == NULL))
  10322. gen->locsig_func = mus_locsig_detour;
  10323. else
  10324. {
  10325. gen->locsig_func = mus_locsig_any;
  10326. if ((mus_is_output(output)) &&
  10327. (mus_out_any_is_safe(output)) &&
  10328. (mus_channels(output) == chans))
  10329. {
  10330. if (rev_chans > 0)
  10331. {
  10332. if ((rev_chans == 1) &&
  10333. (mus_is_output(revput)) &&
  10334. (mus_out_any_is_safe(revput)) &&
  10335. (mus_channels(revput) == 1))
  10336. {
  10337. gen->safe_output = true;
  10338. switch (chans)
  10339. {
  10340. case 1: gen->locsig_func = mus_locsig_safe_mono; break;
  10341. case 2: gen->locsig_func = mus_locsig_safe_stereo; break;
  10342. default: gen->locsig_func = mus_locsig_safe_any; break;
  10343. }
  10344. }
  10345. }
  10346. else
  10347. {
  10348. gen->safe_output = true;
  10349. switch (chans)
  10350. {
  10351. case 1: gen->locsig_func = mus_locsig_safe_mono_no_reverb; break;
  10352. case 2: gen->locsig_func = mus_locsig_safe_stereo_no_reverb; break;
  10353. default: gen->locsig_func = mus_locsig_safe_any_no_reverb; break;
  10354. }
  10355. }
  10356. }
  10357. else
  10358. {
  10359. if (rev_chans > 0)
  10360. {
  10361. if (rev_chans == 1)
  10362. {
  10363. switch (chans)
  10364. {
  10365. case 1: gen->locsig_func = mus_locsig_mono; break;
  10366. case 2: gen->locsig_func = mus_locsig_stereo; break;
  10367. default: gen->locsig_func = mus_locsig_any; break;
  10368. }
  10369. }
  10370. }
  10371. else
  10372. {
  10373. switch (chans)
  10374. {
  10375. case 1: gen->locsig_func = mus_locsig_mono_no_reverb; break;
  10376. case 2: gen->locsig_func = mus_locsig_stereo_no_reverb; break;
  10377. default: gen->locsig_func = mus_locsig_any_no_reverb; break;
  10378. }
  10379. }
  10380. }
  10381. }
  10382. return((mus_any *)gen);
  10383. }
  10384. void mus_locsig(mus_any *ptr, mus_long_t loc, mus_float_t val)
  10385. {
  10386. locs *gen = (locs *)ptr;
  10387. (*(gen->locsig_func))(ptr, loc, val);
  10388. }
  10389. int mus_locsig_channels(mus_any *ptr)
  10390. {
  10391. return(((locs *)ptr)->chans);
  10392. }
  10393. int mus_locsig_reverb_channels(mus_any *ptr)
  10394. {
  10395. return(((locs *)ptr)->rev_chans);
  10396. }
  10397. void mus_move_locsig(mus_any *ptr, mus_float_t degree, mus_float_t distance)
  10398. {
  10399. locs *gen = (locs *)ptr;
  10400. mus_float_t dist;
  10401. if (distance > 1.0)
  10402. dist = 1.0 / distance;
  10403. else dist = 1.0;
  10404. if (gen->rev_chans > 0)
  10405. {
  10406. if (gen->rev_chans > 2)
  10407. memset((void *)(gen->revn), 0, gen->rev_chans * sizeof(mus_float_t));
  10408. mus_locsig_fill(gen->revn, gen->rev_chans, degree, (gen->reverb * sqrt(dist)), gen->type);
  10409. }
  10410. if (gen->chans > 2)
  10411. memset((void *)(gen->outn), 0, gen->chans * sizeof(mus_float_t));
  10412. mus_locsig_fill(gen->outn, gen->chans, degree, dist, gen->type);
  10413. }
  10414. /* ---------------- move-sound ---------------- */
  10415. typedef struct {
  10416. mus_any_class *core;
  10417. mus_any *outn_writer;
  10418. mus_any *revn_writer;
  10419. mus_float_t *outf, *revf;
  10420. int out_channels, rev_channels;
  10421. mus_long_t start, end;
  10422. mus_any *doppler_delay, *doppler_env, *rev_env;
  10423. mus_any **out_delays, **out_envs, **rev_envs;
  10424. int *out_map;
  10425. bool free_arrays, free_gens;
  10426. void *closure;
  10427. void (*detour)(mus_any *ptr, mus_long_t loc);
  10428. } dloc;
  10429. static bool move_sound_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  10430. int mus_move_sound_channels(mus_any *ptr) {return(((dloc *)ptr)->out_channels);}
  10431. int mus_move_sound_reverb_channels(mus_any *ptr) {return(((dloc *)ptr)->rev_channels);}
  10432. static mus_long_t move_sound_length(mus_any *ptr) {return(((dloc *)ptr)->out_channels);} /* need both because return types differ */
  10433. static void move_sound_reset(mus_any *ptr) {}
  10434. mus_float_t *mus_move_sound_outf(mus_any *ptr) {return(((dloc *)ptr)->outf);}
  10435. mus_float_t *mus_move_sound_revf(mus_any *ptr) {return(((dloc *)ptr)->revf);}
  10436. void *mus_move_sound_closure(mus_any *ptr) {return(((dloc *)ptr)->closure);}
  10437. static void *move_sound_set_closure(mus_any *ptr, void *e) {((dloc *)ptr)->closure = e; return(e);}
  10438. void mus_move_sound_set_detour(mus_any *ptr, void (*detour)(mus_any *ptr, mus_long_t val))
  10439. {
  10440. dloc *gen = (dloc *)ptr;
  10441. gen->detour = detour;
  10442. }
  10443. static char *describe_move_sound(mus_any *ptr)
  10444. {
  10445. dloc *gen = (dloc *)ptr;
  10446. char *dopdly = NULL, *dopenv = NULL, *revenv = NULL;
  10447. char *outdlys = NULL, *outenvs = NULL, *revenvs = NULL;
  10448. char *outmap = NULL;
  10449. char *starts = NULL;
  10450. char *str1 = NULL, *str2 = NULL, *str3 = NULL;
  10451. char *allstr = NULL;
  10452. int len;
  10453. starts = mus_format("%s start: %lld, end: %lld, out chans %d, rev chans: %d",
  10454. mus_name(ptr),
  10455. gen->start,
  10456. gen->end,
  10457. gen->out_channels,
  10458. gen->rev_channels);
  10459. dopdly = mus_format("doppler %s", str1 = mus_describe(gen->doppler_delay));
  10460. dopenv = mus_format("doppler %s", str2 = mus_describe(gen->doppler_env));
  10461. revenv = mus_format("global reverb %s", str3 = mus_describe(gen->rev_env));
  10462. outdlys = clm_array_to_string(gen->out_delays, gen->out_channels, "out_delays", " ");
  10463. outenvs = clm_array_to_string(gen->out_envs, gen->out_channels, "out_envs", " ");
  10464. revenvs = clm_array_to_string(gen->rev_envs, gen->rev_channels, "rev_envs", " ");
  10465. outmap = int_array_to_string(gen->out_map, gen->out_channels, "out_map");
  10466. len = 64 + strlen(starts) + strlen(dopdly) + strlen(dopenv) + strlen(revenv) +
  10467. strlen(outdlys) + strlen(outenvs) + strlen(revenvs) + strlen(outmap);
  10468. allstr = (char *)malloc(len * sizeof(char));
  10469. snprintf(allstr, len, "%s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n free: arrays: %s, gens: %s\n",
  10470. starts, dopdly, dopenv, revenv, outdlys, outenvs, revenvs, outmap,
  10471. (gen->free_arrays) ? "true" : "false",
  10472. (gen->free_gens) ? "true" : "false");
  10473. if (str1) free(str1);
  10474. if (str2) free(str2);
  10475. if (str3) free(str3);
  10476. free(starts);
  10477. free(dopdly);
  10478. free(dopenv);
  10479. free(revenv);
  10480. free(outdlys);
  10481. free(outenvs);
  10482. free(revenvs);
  10483. free(outmap);
  10484. return(allstr);
  10485. }
  10486. static void free_move_sound(mus_any *p)
  10487. {
  10488. dloc *ptr = (dloc *)p;
  10489. if (ptr->free_gens)
  10490. {
  10491. int i;
  10492. /* free everything except outer arrays and IO stuff */
  10493. if (ptr->doppler_delay) mus_free(ptr->doppler_delay);
  10494. if (ptr->doppler_env) mus_free(ptr->doppler_env);
  10495. if (ptr->rev_env) mus_free(ptr->rev_env);
  10496. if (ptr->out_delays)
  10497. for (i = 0; i < ptr->out_channels; i++)
  10498. if (ptr->out_delays[i]) mus_free(ptr->out_delays[i]);
  10499. if (ptr->out_envs)
  10500. for (i = 0; i < ptr->out_channels; i++)
  10501. if (ptr->out_envs[i]) mus_free(ptr->out_envs[i]);
  10502. if (ptr->rev_envs)
  10503. for (i = 0; i < ptr->rev_channels; i++)
  10504. if (ptr->rev_envs[i]) mus_free(ptr->rev_envs[i]);
  10505. }
  10506. if (ptr->free_arrays)
  10507. {
  10508. /* free outer arrays */
  10509. if (ptr->out_envs) {free(ptr->out_envs); ptr->out_envs = NULL;}
  10510. if (ptr->rev_envs) {free(ptr->rev_envs); ptr->rev_envs = NULL;}
  10511. if (ptr->out_delays) {free(ptr->out_delays); ptr->out_delays = NULL;}
  10512. if (ptr->out_map) free(ptr->out_map);
  10513. }
  10514. /* we created these in make_move_sound, so it should always be safe to free them */
  10515. if (ptr->outf) free(ptr->outf);
  10516. if (ptr->revf) free(ptr->revf);
  10517. free(ptr);
  10518. }
  10519. static mus_any *dloc_copy(mus_any *ptr)
  10520. {
  10521. dloc *g, *p;
  10522. int i, bytes;
  10523. p = (dloc *)ptr;
  10524. g = (dloc *)malloc(sizeof(dloc));
  10525. memcpy((void *)g, (void *)ptr, sizeof(dloc));
  10526. if (p->outf)
  10527. {
  10528. bytes = p->out_channels * sizeof(mus_float_t);
  10529. g->outf = (mus_float_t *)malloc(bytes);
  10530. memcpy((void *)(g->outf), (void *)(p->outf), bytes);
  10531. }
  10532. if (p->revf)
  10533. {
  10534. bytes = p->rev_channels * sizeof(mus_float_t);
  10535. g->revf = (mus_float_t *)malloc(bytes);
  10536. memcpy((void *)(g->revf), (void *)(p->revf), bytes);
  10537. }
  10538. g->free_arrays = true;
  10539. g->free_gens = true;
  10540. if (p->doppler_delay) g->doppler_delay = mus_copy(p->doppler_delay);
  10541. if (p->doppler_env) g->doppler_env = mus_copy(p->doppler_env);
  10542. if (p->rev_env) g->rev_env = mus_copy(p->rev_env);
  10543. if (p->out_envs)
  10544. {
  10545. g->out_envs = (mus_any **)malloc(p->out_channels * sizeof(mus_any *));
  10546. for (i = 0; i < p->out_channels; i++) g->out_envs[i] = mus_copy(p->out_envs[i]);
  10547. }
  10548. if (p->rev_envs)
  10549. {
  10550. g->rev_envs = (mus_any **)malloc(p->rev_channels * sizeof(mus_any *));
  10551. for (i = 0; i < p->rev_channels; i++) g->rev_envs[i] = mus_copy(p->rev_envs[i]);
  10552. }
  10553. if (p->out_delays)
  10554. {
  10555. g->out_delays = (mus_any **)malloc(p->out_channels * sizeof(mus_any *));
  10556. for (i = 0; i < p->out_channels; i++) g->out_delays[i] = mus_copy(p->out_delays[i]);
  10557. }
  10558. if (p->out_map)
  10559. {
  10560. bytes = p->out_channels * sizeof(int);
  10561. g->out_map = (int *)malloc(bytes);
  10562. memcpy((void *)(g->out_map), (void *)(p->out_map), bytes);
  10563. }
  10564. return((mus_any *)g);
  10565. }
  10566. bool mus_is_move_sound(mus_any *ptr)
  10567. {
  10568. return((ptr) &&
  10569. (ptr->core->type == MUS_MOVE_SOUND));
  10570. }
  10571. mus_float_t mus_move_sound(mus_any *ptr, mus_long_t loc, mus_float_t uval)
  10572. {
  10573. dloc *gen = (dloc *)ptr;
  10574. mus_float_t val;
  10575. int chan;
  10576. if (loc > gen->end) val = 0.0; else val = uval;
  10577. /* initial silence */
  10578. if (loc < gen->start)
  10579. {
  10580. mus_delay_unmodulated(gen->doppler_delay, val);
  10581. /* original calls out_any here with 0.0 -- a no-op */
  10582. return(val);
  10583. }
  10584. /* doppler */
  10585. if (gen->doppler_delay)
  10586. val = mus_delay(gen->doppler_delay, val, mus_env(gen->doppler_env));
  10587. /* direct signal */
  10588. for (chan = 0; chan < gen->out_channels; chan++)
  10589. {
  10590. mus_float_t sample;
  10591. sample = val * mus_env(gen->out_envs[chan]);
  10592. if (gen->out_delays[chan])
  10593. sample = mus_delay_unmodulated(gen->out_delays[chan], sample);
  10594. gen->outf[gen->out_map[chan]] = sample;
  10595. }
  10596. /* reverb */
  10597. if ((gen->rev_env) &&
  10598. (gen->revf))
  10599. {
  10600. val *= mus_env(gen->rev_env);
  10601. if (gen->rev_envs)
  10602. {
  10603. if (gen->rev_channels == 1)
  10604. gen->revf[0] = val * mus_env(gen->rev_envs[0]);
  10605. else
  10606. {
  10607. for (chan = 0; chan < gen->rev_channels; chan++)
  10608. gen->revf[gen->out_map[chan]] = val * mus_env(gen->rev_envs[chan]);
  10609. }
  10610. }
  10611. else gen->revf[0] = val;
  10612. if (gen->revn_writer)
  10613. mus_frample_to_file(gen->revn_writer, loc, gen->revf);
  10614. }
  10615. /* file output */
  10616. if (gen->outn_writer)
  10617. mus_frample_to_file(gen->outn_writer, loc, gen->outf);
  10618. if (gen->detour)
  10619. (*(gen->detour))(ptr, loc);
  10620. return(uval);
  10621. }
  10622. static mus_float_t run_move_sound(mus_any *ptr, mus_float_t arg1, mus_float_t arg2)
  10623. {
  10624. mus_move_sound(ptr, (mus_long_t)arg1, arg2);
  10625. return(arg2);
  10626. }
  10627. static mus_any_class MOVE_SOUND_CLASS = {
  10628. MUS_MOVE_SOUND,
  10629. (char *)S_move_sound,
  10630. &free_move_sound,
  10631. &describe_move_sound,
  10632. &move_sound_equalp,
  10633. 0, 0,
  10634. &move_sound_length,
  10635. 0,
  10636. 0, 0, 0, 0,
  10637. 0, 0,
  10638. 0, 0,
  10639. &run_move_sound,
  10640. MUS_OUTPUT,
  10641. &mus_move_sound_closure,
  10642. &mus_move_sound_channels,
  10643. 0, 0, 0, 0,
  10644. 0, 0,
  10645. 0, 0, 0, 0,
  10646. 0, 0, 0, 0, 0, 0, 0,
  10647. 0, 0,
  10648. 0, 0,
  10649. &move_sound_reset,
  10650. &move_sound_set_closure,
  10651. &dloc_copy
  10652. };
  10653. mus_any *mus_make_move_sound(mus_long_t start, mus_long_t end, int out_channels, int rev_channels,
  10654. mus_any *doppler_delay, mus_any *doppler_env, mus_any *rev_env,
  10655. mus_any **out_delays, mus_any **out_envs, mus_any **rev_envs,
  10656. int *out_map, mus_any *output, mus_any *revput, bool free_arrays, bool free_gens)
  10657. {
  10658. /* most of these args come to us in a list at the lisp/xen level ("dlocs" struct is actually a list)
  10659. * so the make-move-sound function in lisp/xen is (make-move-sound dloc-list output revout)
  10660. * where the trailing args mimic locsig.
  10661. */
  10662. dloc *gen;
  10663. if (out_channels <= 0)
  10664. {
  10665. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_move_sound ": out chans: %d", out_channels);
  10666. return(NULL);
  10667. }
  10668. gen = (dloc *)calloc(1, sizeof(dloc));
  10669. gen->core = &MOVE_SOUND_CLASS;
  10670. gen->start = start;
  10671. gen->end = end;
  10672. gen->out_channels = out_channels;
  10673. gen->rev_channels = rev_channels;
  10674. gen->doppler_delay = doppler_delay;
  10675. gen->doppler_env = doppler_env;
  10676. gen->rev_env = rev_env;
  10677. gen->out_delays = out_delays;
  10678. gen->out_envs = out_envs;
  10679. gen->rev_envs = rev_envs;
  10680. gen->out_map = out_map;
  10681. /* default is to free only what we make ourselves */
  10682. gen->free_gens = free_gens;
  10683. gen->free_arrays = free_arrays;
  10684. gen->outf = (mus_float_t *)calloc(out_channels, sizeof(mus_float_t));
  10685. if (mus_is_output(output))
  10686. gen->outn_writer = output;
  10687. if (rev_channels > 0)
  10688. {
  10689. if (mus_is_output(revput))
  10690. gen->revn_writer = revput;
  10691. gen->revf = (mus_float_t *)calloc(rev_channels, sizeof(mus_float_t));
  10692. }
  10693. return((mus_any *)gen);
  10694. }
  10695. /* ---------------- src ---------------- */
  10696. /* sampling rate conversion */
  10697. /* taken from sweep_srate.c of Perry Cook. To quote Perry:
  10698. *
  10699. * 'The conversion is performed by sinc interpolation.
  10700. * J. O. Smith and P. Gossett, "A Flexible Sampling-Rate Conversion Method,"
  10701. * Proc. of the IEEE Conference on Acoustics, Speech, and Signal Processing, San Diego, CA, March, 1984.
  10702. * There are essentially two cases, one where the conversion factor
  10703. * is less than one, and the sinc table is used as is yielding a sound
  10704. * which is band limited to the 1/2 the new sampling rate (we don't
  10705. * want to create bandwidth where there was none). The other case
  10706. * is where the conversion factor is greater than one and we 'warp'
  10707. * the sinc table to make the final cutoff equal to the original sampling
  10708. * rate /2. Warping the sinc table is based on the similarity theorem
  10709. * of the time and frequency domain, stretching the time domain (sinc
  10710. * table) causes shrinking in the frequency domain.'
  10711. *
  10712. * we also scale the amplitude if interpolating to take into account the broadened sinc
  10713. * this means that isolated pulses get scaled by 1/src, but that's a dumb special case
  10714. */
  10715. typedef struct {
  10716. mus_any_class *core;
  10717. mus_float_t (*feeder)(void *arg, int direction);
  10718. mus_float_t (*block_feeder)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end);
  10719. mus_float_t x;
  10720. mus_float_t incr, width_1;
  10721. int width, lim, start, sinc4;
  10722. int len;
  10723. mus_float_t *data, *sinc_table, *coeffs;
  10724. void *closure;
  10725. } sr;
  10726. #define SRC_SINC_DENSITY 2000
  10727. #define SRC_SINC_WIDTH 10
  10728. #define SRC_SINC_WINDOW_SIZE 8000
  10729. static mus_float_t **sinc_tables = NULL;
  10730. static int *sinc_widths = NULL;
  10731. static int sincs = 0;
  10732. static mus_float_t *sinc = NULL, *sinc_window = NULL;
  10733. static int sinc_size = 0;
  10734. void mus_clear_sinc_tables(void)
  10735. {
  10736. if (sincs)
  10737. {
  10738. int i;
  10739. for (i = 0; i < sincs; i++)
  10740. if (sinc_tables[i])
  10741. free(sinc_tables[i]);
  10742. free(sinc_tables);
  10743. sinc_tables = NULL;
  10744. free(sinc_window);
  10745. sinc_window = NULL;
  10746. free(sinc_widths);
  10747. sinc_widths = NULL;
  10748. sincs = 0;
  10749. }
  10750. }
  10751. static int init_sinc_table(int width)
  10752. {
  10753. int i, size, padded_size, loc;
  10754. mus_float_t win_freq, win_phase;
  10755. #if HAVE_SINCOS
  10756. double sn, snp, cs, csp;
  10757. #endif
  10758. if (width > sinc_size)
  10759. {
  10760. int old_end;
  10761. mus_float_t sinc_phase, sinc_freq;
  10762. if (sinc_size == 0)
  10763. old_end = 1;
  10764. else old_end = sinc_size * SRC_SINC_DENSITY + 4;
  10765. padded_size = width * SRC_SINC_DENSITY + 4;
  10766. if (sinc_size == 0)
  10767. {
  10768. sinc = (mus_float_t *)malloc(padded_size * sizeof(mus_float_t));
  10769. sinc[0] = 1.0;
  10770. }
  10771. else sinc = (mus_float_t *)realloc(sinc, padded_size * sizeof(mus_float_t));
  10772. sinc_size = width;
  10773. sinc_freq = M_PI / (mus_float_t)SRC_SINC_DENSITY;
  10774. sinc_phase = old_end * sinc_freq;
  10775. #if HAVE_SINCOS
  10776. sincos(sinc_freq, &sn, &cs);
  10777. if (old_end == 1)
  10778. {
  10779. sinc[1] = sin(sinc_phase) / (2.0 * sinc_phase);
  10780. old_end++;
  10781. sinc_phase += sinc_freq;
  10782. }
  10783. for (i = old_end; i < padded_size;)
  10784. {
  10785. sincos(sinc_phase, &snp, &csp);
  10786. sinc[i] = snp / (2.0 * sinc_phase);
  10787. i++;
  10788. sinc_phase += sinc_freq;
  10789. sinc[i] = (snp * cs + csp * sn) / (2.0 * sinc_phase);
  10790. i++;
  10791. sinc_phase += sinc_freq;
  10792. }
  10793. #else
  10794. for (i = old_end; i < padded_size; i++, sinc_phase += sinc_freq)
  10795. sinc[i] = sin(sinc_phase) / (2.0 * sinc_phase);
  10796. #endif
  10797. }
  10798. for (i = 0; i < sincs; i++)
  10799. if (sinc_widths[i] == width)
  10800. return(i);
  10801. if (sincs == 0)
  10802. {
  10803. mus_float_t ph, incr;
  10804. incr = M_PI / SRC_SINC_WINDOW_SIZE;
  10805. sinc_window = (mus_float_t *)calloc(SRC_SINC_WINDOW_SIZE + 16, sizeof(mus_float_t));
  10806. for (i = 0, ph = 0.0; i < SRC_SINC_WINDOW_SIZE; i++, ph += incr)
  10807. sinc_window[i] = 1.0 + cos(ph);
  10808. sinc_tables = (mus_float_t **)calloc(8, sizeof(mus_float_t *));
  10809. sinc_widths = (int *)calloc(8, sizeof(int));
  10810. sincs = 8;
  10811. loc = 0;
  10812. }
  10813. else
  10814. {
  10815. loc = -1;
  10816. for (i = 0; i < sincs; i++)
  10817. if (sinc_widths[i] == 0)
  10818. {
  10819. loc = i;
  10820. break;
  10821. }
  10822. if (loc == -1)
  10823. {
  10824. sinc_tables = (mus_float_t **)realloc(sinc_tables, (sincs + 8) * sizeof(mus_float_t *));
  10825. sinc_widths = (int *)realloc(sinc_widths, (sincs + 8) * sizeof(int));
  10826. for (i = sincs; i < (sincs + 8); i++)
  10827. {
  10828. sinc_widths[i] = 0;
  10829. sinc_tables[i] = NULL;
  10830. }
  10831. loc = sincs;
  10832. sincs += 8;
  10833. }
  10834. }
  10835. sinc_widths[loc] = width;
  10836. size = width * SRC_SINC_DENSITY;
  10837. padded_size = size + 4;
  10838. win_freq = (mus_float_t)SRC_SINC_WINDOW_SIZE / (mus_float_t)size;
  10839. sinc_tables[loc] = (mus_float_t *)malloc(padded_size * 2 * sizeof(mus_float_t));
  10840. sinc_tables[loc][padded_size] = 1.0;
  10841. for (i = 1, win_phase = win_freq; i < padded_size; i++, win_phase += win_freq)
  10842. {
  10843. mus_float_t val;
  10844. val = sinc[i] * sinc_window[(int)win_phase];
  10845. sinc_tables[loc][padded_size + i] = val;
  10846. sinc_tables[loc][padded_size - i] = val;
  10847. }
  10848. return(loc);
  10849. }
  10850. bool mus_is_src(mus_any *ptr)
  10851. {
  10852. return((ptr) &&
  10853. (ptr->core->type == MUS_SRC));
  10854. }
  10855. static void free_src_gen(mus_any *srptr)
  10856. {
  10857. sr *srp = (sr *)srptr;
  10858. if (srp->data) free(srp->data);
  10859. if (srp->coeffs) free(srp->coeffs);
  10860. free(srp);
  10861. }
  10862. static mus_any *sr_copy(mus_any *ptr)
  10863. {
  10864. sr *g, *p;
  10865. int bytes;
  10866. p = (sr *)ptr;
  10867. g = (sr *)malloc(sizeof(sr));
  10868. memcpy((void *)g, (void *)ptr, sizeof(sr));
  10869. bytes = (2 * g->lim + 1) * sizeof(mus_float_t);
  10870. g->data = (mus_float_t *)malloc(bytes);
  10871. memcpy((void *)(g->data), (void *)(p->data), bytes);
  10872. if (p->coeffs)
  10873. {
  10874. bytes = p->lim * sizeof(mus_float_t);
  10875. g->coeffs = (mus_float_t *)malloc(bytes);
  10876. memcpy((void *)(g->coeffs), (void *)(p->coeffs), bytes);
  10877. }
  10878. return((mus_any *)g);
  10879. }
  10880. static bool src_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  10881. static char *describe_src(mus_any *ptr)
  10882. {
  10883. sr *gen = (sr *)ptr;
  10884. char *describe_buffer;
  10885. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  10886. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s width: %d, x: %.3f, incr: %.3f, sinc table len: %d",
  10887. mus_name(ptr),
  10888. gen->width, gen->x, gen->incr, gen->len);
  10889. return(describe_buffer);
  10890. }
  10891. static mus_long_t src_length(mus_any *ptr) {return(((sr *)ptr)->width);}
  10892. static mus_float_t run_src_gen(mus_any *srptr, mus_float_t sr_change, mus_float_t unused) {return(mus_src(srptr, sr_change, NULL));}
  10893. static void *src_closure(mus_any *rd) {return(((sr *)rd)->closure);}
  10894. static void *src_set_closure(mus_any *rd, void *e) {((sr *)rd)->closure = e; return(e);}
  10895. static mus_float_t src_increment(mus_any *rd) {return(((sr *)rd)->incr);}
  10896. static mus_float_t src_set_increment(mus_any *rd, mus_float_t val) {((sr *)rd)->incr = val; return(val);}
  10897. static mus_float_t *src_sinc_table(mus_any *rd) {return(((sr *)rd)->sinc_table);}
  10898. static void src_reset(mus_any *ptr)
  10899. {
  10900. sr *gen = (sr *)ptr;
  10901. memset((void *)(gen->data), 0, (gen->lim + 1) * sizeof(mus_float_t));
  10902. gen->x = 0.0;
  10903. /* center the data if possible */
  10904. if (gen->feeder)
  10905. {
  10906. int i, dir = 1;
  10907. if (gen->incr < 0.0) dir = -1;
  10908. for (i = gen->width - 1; i < gen->lim; i++)
  10909. gen->data[i] = gen->feeder(gen->closure, dir);
  10910. }
  10911. gen->start = 0;
  10912. }
  10913. void mus_src_init(mus_any *ptr)
  10914. {
  10915. sr *srp = (sr *)ptr;
  10916. if (srp->feeder)
  10917. {
  10918. int i, dir = 1;
  10919. if (srp->incr < 0.0) dir = -1;
  10920. for (i = srp->width - 1; i < srp->lim; i++)
  10921. {
  10922. srp->data[i] = srp->feeder(srp->closure, dir);
  10923. srp->data[i + srp->lim] = srp->data[i];
  10924. }
  10925. }
  10926. }
  10927. static mus_any_class SRC_CLASS = {
  10928. MUS_SRC,
  10929. (char *)S_src,
  10930. &free_src_gen,
  10931. &describe_src,
  10932. &src_equalp,
  10933. &src_sinc_table, 0,
  10934. &src_length, /* sinc width actually */
  10935. 0,
  10936. 0, 0, 0, 0,
  10937. &fallback_scaler, 0,
  10938. &src_increment,
  10939. &src_set_increment,
  10940. &run_src_gen,
  10941. MUS_NOT_SPECIAL,
  10942. &src_closure,
  10943. 0,
  10944. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  10945. 0, 0, 0, 0, 0, 0, 0,
  10946. 0, 0, 0, 0,
  10947. &src_reset,
  10948. &src_set_closure,
  10949. &sr_copy
  10950. };
  10951. mus_any *mus_make_src_with_init(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure, void (*init)(void *p, mus_any *g))
  10952. {
  10953. /* besides 1, 2, .5, other common cases: 1.5, 3
  10954. */
  10955. if (fabs(srate) > MUS_MAX_CLM_SRC)
  10956. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_src ": srate arg invalid: %f", srate);
  10957. else
  10958. {
  10959. if ((width < 0) || (width > MUS_MAX_CLM_SINC_WIDTH))
  10960. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_src ": width arg invalid: %d", width);
  10961. else
  10962. {
  10963. sr *srp;
  10964. int wid, loc;
  10965. if (width <= 0) width = SRC_SINC_WIDTH;
  10966. if (width < (int)(fabs(srate) * 2))
  10967. wid = (int)(ceil(fabs(srate)) * 2);
  10968. else wid = width;
  10969. if ((srate == 2.0) &&
  10970. ((wid & 1) != 0))
  10971. wid++;
  10972. srp = (sr *)calloc(1, sizeof(sr));
  10973. srp->core = &SRC_CLASS;
  10974. srp->x = 0.0;
  10975. srp->feeder = input;
  10976. srp->block_feeder = NULL;
  10977. srp->closure = closure;
  10978. srp->incr = srate;
  10979. srp->width = wid;
  10980. srp->lim = 2 * wid;
  10981. srp->start = 0;
  10982. srp->len = wid * SRC_SINC_DENSITY;
  10983. srp->width_1 = 1.0 - wid;
  10984. srp->sinc4 = srp->width * SRC_SINC_DENSITY + 4;
  10985. srp->data = (mus_float_t *)calloc(2 * srp->lim + 1, sizeof(mus_float_t));
  10986. loc = init_sinc_table(wid);
  10987. srp->sinc_table = sinc_tables[loc];
  10988. srp->coeffs = NULL;
  10989. if (init)
  10990. init(closure, (mus_any *)srp);
  10991. if (srp->feeder)
  10992. {
  10993. int i, dir = 1;
  10994. if (srate < 0.0) dir = -1;
  10995. for (i = wid - 1; i < srp->lim; i++)
  10996. {
  10997. srp->data[i] = srp->feeder(closure, dir);
  10998. srp->data[i + srp->lim] = srp->data[i];
  10999. }
  11000. /* was i = 0 here but we want the incoming data centered */
  11001. }
  11002. return((mus_any *)srp);
  11003. }
  11004. }
  11005. return(NULL);
  11006. }
  11007. mus_any *mus_make_src(mus_float_t (*input)(void *arg, int direction), mus_float_t srate, int width, void *closure)
  11008. {
  11009. return(mus_make_src_with_init(input, srate, width, closure, NULL));
  11010. }
  11011. mus_float_t mus_src(mus_any *srptr, mus_float_t sr_change, mus_float_t (*input)(void *arg, int direction))
  11012. {
  11013. sr *srp = (sr *)srptr;
  11014. mus_float_t sum, zf, srx, factor;
  11015. int lim, loc, xi;
  11016. bool int_ok;
  11017. mus_float_t *data, *sinc_table;
  11018. lim = srp->lim;
  11019. loc = srp->start;
  11020. data = srp->data;
  11021. sinc_table = srp->sinc_table;
  11022. if (sr_change > MUS_MAX_CLM_SRC)
  11023. sr_change = MUS_MAX_CLM_SRC;
  11024. else
  11025. {
  11026. if (sr_change < -MUS_MAX_CLM_SRC)
  11027. sr_change = -MUS_MAX_CLM_SRC;
  11028. }
  11029. srx = srp->incr + sr_change;
  11030. if (srp->x >= 1.0)
  11031. {
  11032. int i, fsx, dir = 1;
  11033. if (srx < 0.0) dir = -1;
  11034. fsx = (int)(srp->x);
  11035. srp->x -= fsx;
  11036. if (input) {srp->feeder = input; srp->block_feeder = NULL;}
  11037. data[loc] = srp->feeder(srp->closure, dir);
  11038. data[loc + lim] = data[loc];
  11039. loc++;
  11040. if (loc == lim) loc = 0;
  11041. for (i = 1; i < fsx; i++)
  11042. {
  11043. /* there are two copies of the circular data buffer back-to-back so that we can
  11044. * run the convolution below without worrying about the buffer end.
  11045. */
  11046. data[loc] = srp->feeder(srp->closure, dir);
  11047. data[loc + lim] = data[loc];
  11048. loc++;
  11049. if (loc == lim) loc = 0;
  11050. }
  11051. srp->start = loc; /* next time around we start here */
  11052. }
  11053. /* now loc = beginning of data */
  11054. /* if (srx == 0.0) srx = 0.01; */ /* can't decide about this ... */
  11055. if (srx < 0.0) srx = -srx;
  11056. if (srx > 1.0)
  11057. {
  11058. factor = 1.0 / srx;
  11059. /* this is not exact since we're sampling the sinc and so on, but it's close over a wide range */
  11060. zf = factor * (mus_float_t)SRC_SINC_DENSITY;
  11061. xi = (int)(zf + 0.5);
  11062. /* (let ((e (make-env '(0 1 1 1.1) :length 11))) (src-channel e))
  11063. */
  11064. /* we're comparing adding xi lim times to zf and if there's no difference, using the int case */
  11065. if (fabs((xi - zf) * lim) > 2.0) int_ok = false; else int_ok = true;
  11066. }
  11067. else
  11068. {
  11069. factor = 1.0;
  11070. zf = (mus_float_t)SRC_SINC_DENSITY;
  11071. xi = SRC_SINC_DENSITY;
  11072. int_ok = true;
  11073. }
  11074. sum = 0.0;
  11075. if (int_ok)
  11076. {
  11077. int sinc_loc, sinc_incr, last, last10, xs;
  11078. xs = (int)(zf * (srp->width_1 - srp->x));
  11079. sinc_loc = xs + srp->sinc4;
  11080. sinc_incr = xi;
  11081. last = loc + lim;
  11082. last10 = last - 10;
  11083. while (loc <= last10)
  11084. {
  11085. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11086. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11087. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11088. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11089. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11090. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11091. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11092. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11093. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11094. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11095. }
  11096. for (; loc < last; loc++, sinc_loc += sinc_incr)
  11097. sum += data[loc] * sinc_table[sinc_loc];
  11098. }
  11099. else
  11100. {
  11101. mus_float_t sinc_loc, sinc_incr, x;
  11102. int last, last10;
  11103. x = zf * (srp->width_1 - srp->x);
  11104. sinc_loc = x + srp->sinc4;
  11105. sinc_incr = zf;
  11106. last = loc + lim;
  11107. last10 = last - 10;
  11108. while (loc <= last10)
  11109. {
  11110. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11111. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11112. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11113. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11114. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11115. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11116. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11117. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11118. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11119. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11120. }
  11121. for (; loc < last; loc++, sinc_loc += sinc_incr)
  11122. sum += data[loc] * sinc_table[(int)sinc_loc];
  11123. }
  11124. srp->x += srx;
  11125. return(sum * factor);
  11126. }
  11127. void mus_src_to_buffer(mus_any *srptr, mus_float_t (*input)(void *arg, int direction), mus_float_t *out_data, mus_long_t dur)
  11128. {
  11129. /* sr_change = 0.0
  11130. */
  11131. sr *srp = (sr *)srptr;
  11132. mus_float_t sum, x, zf, srx, factor, sincx, srpx;
  11133. int lim, i, xi, xs, dir = 1;
  11134. bool int_ok;
  11135. mus_long_t k;
  11136. mus_float_t *data, *sinc_table;
  11137. lim = srp->lim;
  11138. sincx = (mus_float_t)SRC_SINC_DENSITY;
  11139. data = srp->data;
  11140. sinc_table = srp->sinc_table;
  11141. srx = srp->incr;
  11142. srpx = srp->x;
  11143. if (srx < 0.0)
  11144. {
  11145. dir = -1;
  11146. srx = -srx;
  11147. }
  11148. if (srx > 1.0)
  11149. {
  11150. factor = 1.0 / srx;
  11151. /* this is not exact since we're sampling the sinc and so on, but it's close over a wide range */
  11152. zf = factor * sincx;
  11153. xi = (int)zf;
  11154. if (fabs((xi - zf) * lim) > 2.0) int_ok = false; else int_ok = true;
  11155. }
  11156. else
  11157. {
  11158. factor = 1.0;
  11159. zf = sincx;
  11160. xi = SRC_SINC_DENSITY;
  11161. int_ok = true;
  11162. }
  11163. for (k = 0; k < dur; k++)
  11164. {
  11165. int loc;
  11166. loc = srp->start;
  11167. if (srpx >= 1.0)
  11168. {
  11169. int fsx;
  11170. /* modf here is very slow??! */
  11171. fsx = (int)srpx;
  11172. srpx -= fsx;
  11173. data[loc] = input(srp->closure, dir);
  11174. data[loc + lim] = data[loc];
  11175. loc++;
  11176. if (loc == lim) loc = 0;
  11177. for (i = 1; i < fsx; i++)
  11178. {
  11179. /* there are two copies of the circular data buffer back-to-back so that we can
  11180. * run the convolution below without worrying about the buffer end.
  11181. */
  11182. data[loc] = input(srp->closure, dir);
  11183. data[loc + lim] = data[loc];
  11184. loc++;
  11185. if (loc == lim) loc = 0;
  11186. }
  11187. srp->start = loc; /* next time around we start here */
  11188. }
  11189. sum = 0.0;
  11190. if (int_ok)
  11191. {
  11192. int sinc_loc, sinc_incr, last, last10;
  11193. xs = (int)(zf * (srp->width_1 - srpx));
  11194. sinc_loc = xs + srp->sinc4;
  11195. sinc_incr = xi;
  11196. last = loc + lim;
  11197. last10 = last - 10;
  11198. while (loc <= last10)
  11199. {
  11200. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11201. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11202. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11203. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11204. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11205. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11206. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11207. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11208. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11209. sum += data[loc++] * sinc_table[sinc_loc]; sinc_loc += sinc_incr;
  11210. }
  11211. for (; loc < last; loc++, sinc_loc += sinc_incr)
  11212. sum += data[loc] * sinc_table[sinc_loc];
  11213. }
  11214. else
  11215. {
  11216. mus_float_t sinc_loc, sinc_incr;
  11217. int last, last10;
  11218. x = zf * (srp->width_1 - srpx);
  11219. sinc_loc = x + srp->sinc4;
  11220. sinc_incr = zf;
  11221. last = loc + lim;
  11222. last10 = last - 10;
  11223. while (loc <= last10)
  11224. {
  11225. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11226. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11227. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11228. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11229. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11230. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11231. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11232. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11233. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11234. sum += data[loc++] * sinc_table[(int)sinc_loc]; sinc_loc += sinc_incr;
  11235. }
  11236. for (; loc < last; loc++, sinc_loc += sinc_incr)
  11237. sum += data[loc] * sinc_table[(int)sinc_loc];
  11238. }
  11239. srpx += srx;
  11240. out_data[k] = sum * factor;
  11241. }
  11242. srp->x = srpx;
  11243. }
  11244. /* it was a cold, rainy day...
  11245. * and on an even colder day, I changed this to use a circular data buffer, rather than memmove
  11246. * then changed yet again to use straight buffers
  11247. */
  11248. mus_float_t *mus_src_20(mus_any *srptr, mus_float_t *in_data, mus_long_t dur)
  11249. {
  11250. sr *srp = (sr *)srptr;
  11251. mus_float_t sum;
  11252. int lim, i, width, wid1, wid10, xs, xi;
  11253. mus_long_t k, dur2;
  11254. mus_float_t *out_data, *ldata, *coeffs;
  11255. dur2 = dur / 2 + 1;
  11256. if ((dur & 1) != 0) dur2++;
  11257. out_data = (mus_float_t *)malloc(dur2 * sizeof(mus_float_t));
  11258. lim = srp->lim; /* 2 * width so it's even */
  11259. width = srp->width;
  11260. coeffs = (mus_float_t *)malloc(lim * sizeof(mus_float_t));
  11261. if ((width & 1) != 0)
  11262. xs = (int)((2 + width) * (SRC_SINC_DENSITY / 2)) + 4; /* Humph -- looks like crap -- maybe if odd width use the real one above, or insist on even width */
  11263. else xs = (int)((1 + width) * (SRC_SINC_DENSITY / 2)) + 4;
  11264. xi = SRC_SINC_DENSITY; /* skip a location (coeff=0.0) */
  11265. for (i = 0; i < width; i++, xs += xi)
  11266. coeffs[i] = srp->sinc_table[xs];
  11267. for (i = 0; i < lim; i++)
  11268. in_data[i] = srp->data[i];
  11269. ldata = (mus_float_t *)in_data;
  11270. wid10 = width - 10;
  11271. wid1 = width - 1;
  11272. for (k = 0; k < dur2; k++, ldata += 2)
  11273. {
  11274. int j;
  11275. sum = ldata[wid1];
  11276. i = 0;
  11277. j = 0;
  11278. while (i <= wid10)
  11279. {
  11280. sum += (ldata[j] * coeffs[i++]); j += 2;
  11281. sum += (ldata[j] * coeffs[i++]); j += 2;
  11282. sum += (ldata[j] * coeffs[i++]); j += 2;
  11283. sum += (ldata[j] * coeffs[i++]); j += 2;
  11284. sum += (ldata[j] * coeffs[i++]); j += 2;
  11285. sum += (ldata[j] * coeffs[i++]); j += 2;
  11286. sum += (ldata[j] * coeffs[i++]); j += 2;
  11287. sum += (ldata[j] * coeffs[i++]); j += 2;
  11288. sum += (ldata[j] * coeffs[i++]); j += 2;
  11289. sum += (ldata[j] * coeffs[i++]); j += 2;
  11290. }
  11291. for (; i < width; i++, j += 2)
  11292. sum += (ldata[j] * coeffs[i]);
  11293. out_data[k] = sum * 0.5;
  11294. }
  11295. free(coeffs);
  11296. return(out_data);
  11297. }
  11298. mus_float_t *mus_src_05(mus_any *srptr, mus_float_t *in_data, mus_long_t dur)
  11299. {
  11300. sr *srp = (sr *)srptr;
  11301. mus_float_t sum;
  11302. int lim, i, width, wid1, wid10, xs, xi;
  11303. mus_long_t k, dur2;
  11304. mus_float_t *out_data, *ldata, *coeffs;
  11305. dur2 = dur * 2;
  11306. out_data = (mus_float_t *)malloc((dur2 + 1) * sizeof(mus_float_t));
  11307. out_data[dur2] = 0.0;
  11308. lim = srp->lim;
  11309. width = srp->width;
  11310. coeffs = (mus_float_t *)malloc(lim * sizeof(mus_float_t));
  11311. xs = (SRC_SINC_DENSITY / 2) + 4;
  11312. xi = SRC_SINC_DENSITY;
  11313. for (i = 0; i < lim; i++, xs += xi)
  11314. coeffs[i] = srp->sinc_table[xs];
  11315. for (i = 0; i < lim; i++)
  11316. in_data[i] = srp->data[i];
  11317. ldata = (mus_float_t *)in_data;
  11318. wid10 = lim - 10;
  11319. wid1 = width - 1;
  11320. for (k = 0; k < dur2; k += 2)
  11321. {
  11322. out_data[k] = ldata[wid1];
  11323. sum = 0.0;
  11324. i = 0;
  11325. while (i <= wid10)
  11326. {
  11327. sum += (ldata[i] * coeffs[i]); i++;
  11328. sum += (ldata[i] * coeffs[i]); i++;
  11329. sum += (ldata[i] * coeffs[i]); i++;
  11330. sum += (ldata[i] * coeffs[i]); i++;
  11331. sum += (ldata[i] * coeffs[i]); i++;
  11332. sum += (ldata[i] * coeffs[i]); i++;
  11333. sum += (ldata[i] * coeffs[i]); i++;
  11334. sum += (ldata[i] * coeffs[i]); i++;
  11335. sum += (ldata[i] * coeffs[i]); i++;
  11336. sum += (ldata[i] * coeffs[i]); i++;
  11337. }
  11338. for (; i < lim; i++)
  11339. sum += (ldata[i] * coeffs[i]);
  11340. out_data[k + 1] = sum;
  11341. ldata++;
  11342. }
  11343. free(coeffs);
  11344. return(out_data);
  11345. }
  11346. /* ---------------- granulate ---------------- */
  11347. typedef struct {
  11348. mus_any_class *core;
  11349. mus_float_t (*rd)(void *arg, int direction);
  11350. mus_float_t (*block_rd)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end);
  11351. int s20;
  11352. int s50;
  11353. int rmp;
  11354. mus_float_t amp;
  11355. int cur_out;
  11356. int input_hop;
  11357. int ctr;
  11358. int output_hop;
  11359. mus_float_t *out_data; /* output buffer */
  11360. int out_data_len;
  11361. mus_float_t *in_data; /* input buffer */
  11362. int in_data_len;
  11363. void *closure;
  11364. int (*edit)(void *closure);
  11365. mus_float_t *grain; /* grain data */
  11366. int grain_len;
  11367. bool first_samp;
  11368. unsigned long randx; /* gen-local random number seed */
  11369. } grn_info;
  11370. bool mus_is_granulate(mus_any *ptr)
  11371. {
  11372. return((ptr) &&
  11373. (ptr->core->type == MUS_GRANULATE));
  11374. }
  11375. static bool granulate_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  11376. static char *describe_granulate(mus_any *ptr)
  11377. {
  11378. grn_info *gen = (grn_info *)ptr;
  11379. char *describe_buffer;
  11380. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  11381. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s expansion: %.3f (%d/%d), scaler: %.3f, length: %.3f secs (%d samps), ramp: %.3f",
  11382. mus_name(ptr),
  11383. (mus_float_t)(gen->output_hop) / (mus_float_t)(gen->input_hop),
  11384. gen->input_hop, gen->output_hop,
  11385. gen->amp,
  11386. (mus_float_t)(gen->grain_len) / (mus_float_t)sampling_rate, gen->grain_len,
  11387. (mus_float_t)(gen->rmp) / (mus_float_t)sampling_rate);
  11388. return(describe_buffer);
  11389. }
  11390. static void free_granulate(mus_any *ptr)
  11391. {
  11392. grn_info *gen = (grn_info *)ptr;
  11393. if (gen->out_data) free(gen->out_data);
  11394. if (gen->in_data) free(gen->in_data);
  11395. if (gen->grain) free(gen->grain);
  11396. free(gen);
  11397. }
  11398. static mus_any *grn_info_copy(mus_any *ptr)
  11399. {
  11400. grn_info *g, *p;
  11401. int bytes;
  11402. p = (grn_info *)ptr;
  11403. g = (grn_info *)malloc(sizeof(grn_info));
  11404. memcpy((void *)g, (void *)ptr, sizeof(grn_info));
  11405. bytes = g->out_data_len * sizeof(mus_float_t);
  11406. g->out_data = (mus_float_t *)malloc(bytes);
  11407. memcpy((void *)(g->out_data), (void *)(p->out_data), bytes);
  11408. bytes = g->in_data_len * sizeof(mus_float_t);
  11409. g->in_data = (mus_float_t *)malloc(bytes);
  11410. memcpy((void *)(g->in_data), (void *)(p->in_data), bytes);
  11411. g->grain = (mus_float_t *)malloc(bytes);
  11412. memcpy((void *)(g->grain), (void *)(p->grain), bytes);
  11413. return((mus_any *)g);
  11414. }
  11415. static mus_long_t grn_length(mus_any *ptr) {return(((grn_info *)ptr)->grain_len);}
  11416. static mus_long_t grn_set_length(mus_any *ptr, mus_long_t val)
  11417. {
  11418. grn_info *gen = ((grn_info *)ptr);
  11419. if ((val > 0) && (val < gen->out_data_len))
  11420. gen->grain_len = (int)val; /* larger -> segfault */
  11421. return(gen->grain_len);
  11422. }
  11423. static mus_float_t grn_scaler(mus_any *ptr) {return(((grn_info *)ptr)->amp);}
  11424. static mus_float_t grn_set_scaler(mus_any *ptr, mus_float_t val) {((grn_info *)ptr)->amp = val; return(val);}
  11425. static mus_float_t grn_frequency(mus_any *ptr) {return(((mus_float_t)((grn_info *)ptr)->output_hop) / (mus_float_t)sampling_rate);}
  11426. static mus_float_t grn_set_frequency(mus_any *ptr, mus_float_t val) {((grn_info *)ptr)->output_hop = (int)((mus_float_t)sampling_rate * val); return(val);}
  11427. static void *grn_closure(mus_any *rd) {return(((grn_info *)rd)->closure);}
  11428. static void *grn_set_closure(mus_any *rd, void *e) {((grn_info *)rd)->closure = e; return(e);}
  11429. static mus_float_t grn_increment(mus_any *ptr)
  11430. {
  11431. grn_info *gen = ((grn_info *)ptr);
  11432. return(((mus_float_t)(gen->output_hop)) / ((mus_float_t)(gen->input_hop)));
  11433. }
  11434. static mus_float_t grn_set_increment(mus_any *ptr, mus_float_t val)
  11435. {
  11436. grn_info *gen = ((grn_info *)ptr);
  11437. if (val != 0.0)
  11438. gen->input_hop = (int)(gen->output_hop / val);
  11439. return(val);
  11440. }
  11441. static mus_long_t grn_hop(mus_any *ptr) {return(((grn_info *)ptr)->output_hop);}
  11442. static mus_long_t grn_set_hop(mus_any *ptr, mus_long_t val) {((grn_info *)ptr)->output_hop = (int)val; return(val);}
  11443. static mus_long_t grn_ramp(mus_any *ptr) {return(((grn_info *)ptr)->rmp);}
  11444. static mus_long_t grn_set_ramp(mus_any *ptr, mus_long_t val)
  11445. {
  11446. grn_info *gen = (grn_info *)ptr;
  11447. if (val < (gen->grain_len * .5))
  11448. gen->rmp = (int)val;
  11449. return(val);
  11450. }
  11451. static mus_float_t *granulate_data(mus_any *ptr) {return(((grn_info *)ptr)->grain);}
  11452. int mus_granulate_grain_max_length(mus_any *ptr) {return(((grn_info *)ptr)->in_data_len);}
  11453. static mus_long_t grn_location(mus_any *ptr) {return((mus_long_t)(((grn_info *)ptr)->randx));}
  11454. static mus_long_t grn_set_location(mus_any *ptr, mus_long_t val) {((grn_info *)ptr)->randx = (unsigned long)val; return(val);}
  11455. static mus_float_t run_granulate(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_granulate(ptr, NULL));}
  11456. static void grn_reset(mus_any *ptr)
  11457. {
  11458. grn_info *gen = (grn_info *)ptr;
  11459. gen->cur_out = 0;
  11460. gen->ctr = 0;
  11461. memset((void *)(gen->out_data), 0, gen->out_data_len * sizeof(mus_float_t));
  11462. memset((void *)(gen->in_data), 0, gen->in_data_len * sizeof(mus_float_t));
  11463. memset((void *)(gen->grain), 0, gen->in_data_len * sizeof(mus_float_t));
  11464. gen->first_samp = true;
  11465. }
  11466. static int grn_irandom(grn_info *spd, int amp)
  11467. {
  11468. /* gen-local next_random */
  11469. spd->randx = spd->randx * 1103515245 + 12345;
  11470. return((int)(amp * INVERSE_MAX_RAND2 * ((mus_float_t)((unsigned int)(spd->randx >> 16) & 32767))));
  11471. }
  11472. static mus_any_class GRANULATE_CLASS = {
  11473. MUS_GRANULATE,
  11474. (char *)S_granulate,
  11475. &free_granulate,
  11476. &describe_granulate,
  11477. &granulate_equalp,
  11478. &granulate_data, 0,
  11479. &grn_length, /* segment-length */
  11480. &grn_set_length,
  11481. &grn_frequency, /* spd-out */
  11482. &grn_set_frequency,
  11483. 0, 0,
  11484. &grn_scaler, /* segment-scaler */
  11485. &grn_set_scaler,
  11486. &grn_increment,
  11487. &grn_set_increment,
  11488. &run_granulate,
  11489. MUS_NOT_SPECIAL,
  11490. &grn_closure,
  11491. 0,
  11492. 0, 0, 0, 0, 0, 0,
  11493. &grn_hop, &grn_set_hop,
  11494. &grn_ramp, &grn_set_ramp,
  11495. 0, 0, 0, 0,
  11496. &grn_location, &grn_set_location, /* local randx */
  11497. 0, 0, 0, 0, 0,
  11498. &grn_reset,
  11499. &grn_set_closure,
  11500. &grn_info_copy
  11501. };
  11502. mus_any *mus_make_granulate(mus_float_t (*input)(void *arg, int direction),
  11503. mus_float_t expansion, mus_float_t length, mus_float_t scaler,
  11504. mus_float_t hop, mus_float_t ramp, mus_float_t jitter, int max_size,
  11505. int (*edit)(void *closure),
  11506. void *closure)
  11507. {
  11508. grn_info *spd;
  11509. int outlen;
  11510. outlen = (int)(sampling_rate * (hop + length));
  11511. if (max_size > outlen) outlen = max_size;
  11512. if (expansion <= 0.0)
  11513. {
  11514. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_granulate ": expansion must be > 0.0: %f", expansion);
  11515. return(NULL);
  11516. }
  11517. if (outlen <= 0)
  11518. {
  11519. mus_error(MUS_NO_LENGTH, S_make_granulate ": size is %d (hop: %f, segment-length: %f)?", outlen, hop, length);
  11520. return(NULL);
  11521. }
  11522. if ((hop * sampling_rate) < expansion)
  11523. {
  11524. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_granulate ": expansion (%f) must be < hop * srate (%f)", expansion, hop * sampling_rate);
  11525. return(NULL);
  11526. }
  11527. spd = (grn_info *)malloc(sizeof(grn_info));
  11528. spd->core = &GRANULATE_CLASS;
  11529. spd->cur_out = 0;
  11530. spd->ctr = 0;
  11531. spd->grain_len = (int)(ceil(length * sampling_rate));
  11532. spd->rmp = (int)(ramp * spd->grain_len);
  11533. spd->amp = scaler;
  11534. spd->output_hop = (int)(hop * sampling_rate);
  11535. spd->input_hop = (int)((mus_float_t)(spd->output_hop) / expansion);
  11536. spd->s20 = 2 * (int)(jitter * sampling_rate * hop); /* was *.05 here and *.02 below */
  11537. /* added "2 *" 21-Mar-05 and replaced irandom with (grn)mus_irandom below */
  11538. spd->s50 = (int)(jitter * sampling_rate * hop * 0.4);
  11539. spd->out_data_len = outlen;
  11540. spd->out_data = (mus_float_t *)calloc(spd->out_data_len, sizeof(mus_float_t));
  11541. spd->in_data_len = outlen + spd->s20 + 1;
  11542. spd->in_data = (mus_float_t *)malloc(spd->in_data_len * sizeof(mus_float_t));
  11543. spd->rd = input;
  11544. spd->block_rd = NULL;
  11545. spd->closure = closure;
  11546. spd->edit = edit;
  11547. spd->grain = (mus_float_t *)malloc(spd->in_data_len * sizeof(mus_float_t));
  11548. spd->first_samp = true;
  11549. spd->randx = mus_rand_seed(); /* caller can override this via the mus_location method */
  11550. next_random();
  11551. return((mus_any *)spd);
  11552. }
  11553. void mus_granulate_set_edit_function(mus_any *ptr, int (*edit)(void *closure))
  11554. {
  11555. grn_info *gen = (grn_info *)ptr;
  11556. if (!(gen->grain))
  11557. gen->grain = (mus_float_t *)calloc(gen->in_data_len, sizeof(mus_float_t));
  11558. gen->edit = edit;
  11559. }
  11560. mus_float_t mus_granulate_with_editor(mus_any *ptr, mus_float_t (*input)(void *arg, int direction), int (*edit)(void *closure))
  11561. {
  11562. /* in_data_len is the max grain size (:maxsize arg), not the current grain size
  11563. * out_data_len is the size of the output buffer
  11564. * grain_len is the current grain size
  11565. * cur_out is the out_data buffer location where we need to add in the next grain
  11566. * ctr is where we are now in out_data
  11567. */
  11568. grn_info *spd = (grn_info *)ptr;
  11569. mus_float_t result = 0.0;
  11570. if (spd->ctr < spd->out_data_len)
  11571. result = spd->out_data[spd->ctr]; /* else return 0.0 */
  11572. spd->ctr++;
  11573. if (spd->ctr >= spd->cur_out) /* time for next grain */
  11574. {
  11575. /* set up edit/input functions and possible outside-accessible grain array */
  11576. int i;
  11577. int (*spd_edit)(void *closure) = edit;
  11578. if (input) {spd->rd = input; spd->block_rd = NULL;}
  11579. if (spd_edit == NULL) spd_edit = spd->edit;
  11580. if (spd->first_samp)
  11581. {
  11582. /* fill up in_data, out_data is already cleared */
  11583. if (spd->block_rd)
  11584. spd->block_rd(spd->closure, 1, spd->in_data, 0, spd->in_data_len);
  11585. else
  11586. {
  11587. for (i = 0; i < spd->in_data_len; i++)
  11588. spd->in_data[i] = spd->rd(spd->closure, 1);
  11589. }
  11590. }
  11591. else
  11592. {
  11593. /* align output buffer to flush the data we've already output, and zero out new trailing portion */
  11594. if (spd->cur_out >= spd->out_data_len)
  11595. {
  11596. /* entire buffer has been output, and in fact we've been sending 0's for awhile to fill out hop */
  11597. memset((void *)(spd->out_data), 0, spd->out_data_len * sizeof(mus_float_t)); /* so zero the entire thing (it's all old) */
  11598. }
  11599. else
  11600. {
  11601. /* move yet-un-output data to 0, zero trailers */
  11602. int good_samps;
  11603. good_samps = (spd->out_data_len - spd->cur_out);
  11604. memmove((void *)(spd->out_data), (void *)(spd->out_data + spd->cur_out), good_samps * sizeof(mus_float_t));
  11605. memset((void *)(spd->out_data + good_samps), 0, spd->cur_out * sizeof(mus_float_t)); /* must be cur_out trailing samples to 0 */
  11606. }
  11607. /* align input buffer */
  11608. if (spd->input_hop > spd->in_data_len)
  11609. {
  11610. /* need to flush enough samples to accommodate the fact that the hop is bigger than our data buffer */
  11611. for (i = spd->in_data_len; i < spd->input_hop; i++) spd->rd(spd->closure, 1);
  11612. /* then get a full input buffer */
  11613. if (spd->block_rd)
  11614. spd->block_rd(spd->closure, 1, spd->in_data, 0, spd->in_data_len);
  11615. else
  11616. {
  11617. for (i = 0; i < spd->in_data_len; i++)
  11618. spd->in_data[i] = spd->rd(spd->closure, 1);
  11619. }
  11620. }
  11621. else
  11622. {
  11623. /* align input buffer with current input hop location */
  11624. int good_samps;
  11625. good_samps = (spd->in_data_len - spd->input_hop);
  11626. memmove((void *)(spd->in_data), (void *)(spd->in_data + spd->input_hop), good_samps * sizeof(mus_float_t));
  11627. if (spd->block_rd)
  11628. spd->block_rd(spd->closure, 1, spd->in_data, good_samps, spd->in_data_len);
  11629. else
  11630. {
  11631. for (i = good_samps; i < spd->in_data_len; i++)
  11632. spd->in_data[i] = spd->rd(spd->closure, 1);
  11633. }
  11634. }
  11635. }
  11636. /* create current grain */
  11637. {
  11638. int lim, curstart, j;
  11639. lim = spd->grain_len;
  11640. curstart = grn_irandom(spd, spd->s20); /* start location in input buffer */
  11641. if ((curstart + spd->grain_len) > spd->in_data_len)
  11642. lim = (spd->in_data_len - curstart);
  11643. if (lim > spd->grain_len)
  11644. lim = spd->grain_len;
  11645. else
  11646. {
  11647. if (lim < spd->grain_len)
  11648. memset((void *)(spd->grain), 0, (spd->grain_len - lim) * sizeof(mus_float_t));
  11649. }
  11650. if (spd->rmp > 0)
  11651. {
  11652. int steady_end, up_end;
  11653. mus_float_t amp = 0.0, incr;
  11654. steady_end = (spd->grain_len - spd->rmp);
  11655. incr = (mus_float_t)(spd->amp) / (mus_float_t)(spd->rmp);
  11656. up_end = spd->rmp;
  11657. if (up_end > lim) up_end = lim;
  11658. for (i = 0, j = curstart; i < up_end; i++, j++)
  11659. {
  11660. spd->grain[i] = (amp * spd->in_data[j]);
  11661. amp += incr;
  11662. }
  11663. if (steady_end > lim) steady_end = lim;
  11664. for (; i < steady_end; i++, j++)
  11665. spd->grain[i] = (amp * spd->in_data[j]);
  11666. for (; i < lim; i++, j++)
  11667. {
  11668. spd->grain[i] = (amp * spd->in_data[j]);
  11669. amp -= incr;
  11670. }
  11671. }
  11672. else
  11673. {
  11674. /* ramp is 0.0, so just scale the input buffer by the current amp */
  11675. if (spd->amp == 1.0)
  11676. memcpy((void *)(spd->grain), (void *)(spd->in_data + curstart), lim * sizeof(mus_float_t));
  11677. else
  11678. {
  11679. for (i = 0, j = curstart; i < lim; i++, j++)
  11680. spd->grain[i] = (spd->amp * spd->in_data[j]);
  11681. }
  11682. }
  11683. }
  11684. /* add new grain into output buffer */
  11685. {
  11686. int new_len;
  11687. if (spd_edit)
  11688. {
  11689. new_len = (*spd_edit)(spd->closure);
  11690. if (new_len <= 0)
  11691. new_len = spd->grain_len;
  11692. else
  11693. {
  11694. if (new_len > spd->out_data_len)
  11695. new_len = spd->out_data_len;
  11696. }
  11697. }
  11698. else new_len = spd->grain_len;
  11699. if (new_len > spd->out_data_len) /* can be off-by-one here if hop is just barely greater then 0.0 (user is screwing around...) */
  11700. new_len = spd->out_data_len;
  11701. for (i = 0; i < new_len; i++)
  11702. spd->out_data[i] += spd->grain[i];
  11703. }
  11704. /* set location of next grain calculation */
  11705. spd->ctr = 0;
  11706. spd->cur_out = spd->output_hop + grn_irandom(spd, 2 * spd->s50) - (spd->s50 >> 1);
  11707. /* this form suggested by Marc Lehmann */
  11708. /* "2 *" added 21-Mar-05 and irandom replaced with mus_irandom, grn_irandom 28-Feb-06 */
  11709. /* use of gen-local random sequence suggested by Kjetil Matheussen (to keep multi-channel grns in sync) */
  11710. if (spd->cur_out < 0) spd->cur_out = 0;
  11711. if (spd->first_samp)
  11712. {
  11713. spd->first_samp = false;
  11714. spd->ctr = 1;
  11715. return(spd->out_data[0]);
  11716. }
  11717. }
  11718. return(result);
  11719. }
  11720. mus_float_t mus_granulate(mus_any *ptr, mus_float_t (*input)(void *arg, int direction))
  11721. {
  11722. return(mus_granulate_with_editor(ptr, input, NULL));
  11723. }
  11724. /* ---------------- Fourier transform ---------------- */
  11725. /* fft of mus_float_t data in zero-based arrays
  11726. */
  11727. static void mus_big_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is);
  11728. #if HAVE_FFTW3 && HAVE_COMPLEX_TRIG
  11729. static fftw_complex *c_in_data = NULL, *c_out_data = NULL;
  11730. static fftw_plan c_r_plan, c_i_plan;
  11731. static int last_c_fft_size = 0;
  11732. static void mus_fftw_with_imag(mus_float_t *rl, mus_float_t *im, int n, int dir)
  11733. {
  11734. int i, n4;
  11735. if (n != last_c_fft_size)
  11736. {
  11737. if (c_in_data)
  11738. {
  11739. fftw_free(c_in_data);
  11740. fftw_free(c_out_data);
  11741. fftw_destroy_plan(c_r_plan);
  11742. fftw_destroy_plan(c_i_plan);
  11743. }
  11744. c_in_data = (fftw_complex *)fftw_malloc(n * sizeof(fftw_complex)); /* rl/im data is mus_float_t */
  11745. c_out_data = (fftw_complex *)fftw_malloc(n * sizeof(fftw_complex));
  11746. c_r_plan = fftw_plan_dft_1d(n, c_in_data, c_out_data, FFTW_FORWARD, FFTW_ESTIMATE);
  11747. c_i_plan = fftw_plan_dft_1d(n, c_in_data, c_out_data, FFTW_BACKWARD, FFTW_ESTIMATE);
  11748. last_c_fft_size = n;
  11749. }
  11750. n4 = n - 4;
  11751. i = 0;
  11752. while (i <= n4)
  11753. {
  11754. /* adding code to avoid this loop saves essentially nothing, mainly because the great majority of the calls
  11755. * are actually handling two real arrays at once -- the imag=0 case is 1/10 of the total. In the zero case,
  11756. * the savings here is about 10%, but that is swamped by the fft itself (say 5-10 in c*).
  11757. * using the new split array code (see below) saves essentially nothing -- perhaps 1 to 2% overall.
  11758. */
  11759. c_in_data[i] = rl[i] + _Complex_I * im[i];
  11760. i++;
  11761. c_in_data[i] = rl[i] + _Complex_I * im[i];
  11762. i++;
  11763. c_in_data[i] = rl[i] + _Complex_I * im[i];
  11764. i++;
  11765. c_in_data[i] = rl[i] + _Complex_I * im[i];
  11766. i++;
  11767. }
  11768. for (; i < n; i++)
  11769. c_in_data[i] = rl[i] + _Complex_I * im[i];
  11770. if (dir == -1)
  11771. fftw_execute(c_r_plan);
  11772. else fftw_execute(c_i_plan);
  11773. i = 0;
  11774. while (i <= n4)
  11775. {
  11776. rl[i] = creal(c_out_data[i]);
  11777. im[i] = cimag(c_out_data[i]);
  11778. i++;
  11779. rl[i] = creal(c_out_data[i]);
  11780. im[i] = cimag(c_out_data[i]);
  11781. i++;
  11782. rl[i] = creal(c_out_data[i]);
  11783. im[i] = cimag(c_out_data[i]);
  11784. i++;
  11785. rl[i] = creal(c_out_data[i]);
  11786. im[i] = cimag(c_out_data[i]);
  11787. i++;
  11788. }
  11789. for (; i < n; i++)
  11790. {
  11791. rl[i] = creal(c_out_data[i]);
  11792. im[i] = cimag(c_out_data[i]);
  11793. }
  11794. }
  11795. void mus_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is)
  11796. {
  11797. /* simple timing tests indicate fftw is slightly faster than mus_fft in this context
  11798. */
  11799. if (n < (1 << 30))
  11800. mus_fftw_with_imag(rl, im, n, is);
  11801. else mus_big_fft(rl, im, n, is);
  11802. }
  11803. #else
  11804. static void mus_scramble(mus_float_t *rl, mus_float_t *im, int n)
  11805. {
  11806. /* bit reversal */
  11807. int i, j;
  11808. mus_float_t vr, vi;
  11809. j = 0;
  11810. for (i = 0; i < n; i++)
  11811. {
  11812. int m;
  11813. if (j > i)
  11814. {
  11815. vr = rl[j];
  11816. vi = im[j];
  11817. rl[j] = rl[i];
  11818. im[j] = im[i];
  11819. rl[i] = vr;
  11820. im[i] = vi;
  11821. }
  11822. m = n >> 1;
  11823. while ((m >= 2) && (j >= m))
  11824. {
  11825. j -= m;
  11826. m = m >> 1;
  11827. }
  11828. j += m;
  11829. }
  11830. }
  11831. void mus_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is)
  11832. {
  11833. /* standard fft: real part in rl, imaginary in im,
  11834. * rl and im are zero-based.
  11835. * see fxt/simplfft/fft.c (Joerg Arndt)
  11836. */
  11837. int m, j, mh, ldm, lg, i, i2, j2, imh;
  11838. mus_float_t u, vr, vi, angle;
  11839. if (n >= (1 << 30))
  11840. {
  11841. mus_big_fft(rl, im, n, is);
  11842. return;
  11843. }
  11844. imh = (int)(log(n + 1) / log(2.0));
  11845. mus_scramble(rl, im, n);
  11846. m = 2;
  11847. ldm = 1;
  11848. mh = n >> 1;
  11849. angle = (M_PI * is);
  11850. for (lg = 0; lg < imh; lg++)
  11851. {
  11852. mus_float_t c, s, ur, ui;
  11853. c = cos(angle);
  11854. s = sin(angle);
  11855. ur = 1.0;
  11856. ui = 0.0;
  11857. for (i2 = 0; i2 < ldm; i2++)
  11858. {
  11859. i = i2;
  11860. j = i2 + ldm;
  11861. for (j2 = 0; j2 < mh; j2++)
  11862. {
  11863. vr = ur * rl[j] - ui * im[j];
  11864. vi = ur * im[j] + ui * rl[j];
  11865. rl[j] = rl[i] - vr;
  11866. im[j] = im[i] - vi;
  11867. rl[i] += vr;
  11868. im[i] += vi;
  11869. i += m;
  11870. j += m;
  11871. }
  11872. u = ur;
  11873. ur = (ur * c) - (ui * s);
  11874. ui = (ui * c) + (u * s);
  11875. }
  11876. mh >>= 1;
  11877. ldm = m;
  11878. angle *= 0.5;
  11879. m <<= 1;
  11880. }
  11881. }
  11882. #endif
  11883. static void mus_big_fft(mus_float_t *rl, mus_float_t *im, mus_long_t n, int is)
  11884. {
  11885. mus_long_t m, j, mh, ldm, i, i2, j2;
  11886. int imh, lg;
  11887. mus_float_t u, vr, vi, angle;
  11888. imh = (int)(log(n + 1) / log(2.0));
  11889. j = 0;
  11890. for (i = 0; i < n; i++)
  11891. {
  11892. if (j > i)
  11893. {
  11894. vr = rl[j];
  11895. vi = im[j];
  11896. rl[j] = rl[i];
  11897. im[j] = im[i];
  11898. rl[i] = vr;
  11899. im[i] = vi;
  11900. }
  11901. m = n >> 1;
  11902. while ((m >= 2) && (j >= m))
  11903. {
  11904. j -= m;
  11905. m = m >> 1;
  11906. }
  11907. j += m;
  11908. }
  11909. m = 2;
  11910. ldm = 1;
  11911. mh = n >> 1;
  11912. angle = (M_PI * is);
  11913. for (lg = 0; lg < imh; lg++)
  11914. {
  11915. mus_float_t c, s, ur, ui;
  11916. c = cos(angle);
  11917. s = sin(angle);
  11918. ur = 1.0;
  11919. ui = 0.0;
  11920. for (i2 = 0; i2 < ldm; i2++)
  11921. {
  11922. i = i2;
  11923. j = i2 + ldm;
  11924. for (j2 = 0; j2 < mh; j2++)
  11925. {
  11926. vr = ur * rl[j] - ui * im[j];
  11927. vi = ur * im[j] + ui * rl[j];
  11928. rl[j] = rl[i] - vr;
  11929. im[j] = im[i] - vi;
  11930. rl[i] += vr;
  11931. im[i] += vi;
  11932. i += m;
  11933. j += m;
  11934. }
  11935. u = ur;
  11936. ur = (ur * c) - (ui * s);
  11937. ui = (ui * c) + (u * s);
  11938. }
  11939. mh >>= 1;
  11940. ldm = m;
  11941. angle *= 0.5;
  11942. m <<= 1;
  11943. }
  11944. }
  11945. #if HAVE_GSL
  11946. #include <gsl/gsl_sf_bessel.h>
  11947. mus_float_t mus_bessi0(mus_float_t x)
  11948. {
  11949. gsl_sf_result res;
  11950. gsl_sf_bessel_I0_e(x, &res);
  11951. return((mus_float_t)(res.val));
  11952. }
  11953. #else
  11954. mus_float_t mus_bessi0(mus_float_t x)
  11955. {
  11956. if (x == 0.0) return(1.0);
  11957. if (fabs(x) <= 15.0)
  11958. {
  11959. mus_float_t z, denominator, numerator;
  11960. z = x * x;
  11961. numerator = (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z * (z *
  11962. 0.210580722890567e-22 + 0.380715242345326e-19) +
  11963. 0.479440257548300e-16) + 0.435125971262668e-13) +
  11964. 0.300931127112960e-10) + 0.160224679395361e-7) +
  11965. 0.654858370096785e-5) + 0.202591084143397e-2) +
  11966. 0.463076284721000e0) + 0.754337328948189e2) +
  11967. 0.830792541809429e4) + 0.571661130563785e6) +
  11968. 0.216415572361227e8) + 0.356644482244025e9) +
  11969. 0.144048298227235e10);
  11970. denominator = (z * (z * (z - 0.307646912682801e4) +
  11971. 0.347626332405882e7) - 0.144048298227235e10);
  11972. return(-numerator / denominator);
  11973. }
  11974. return(1.0);
  11975. }
  11976. #endif
  11977. #if HAVE_COMPLEX_TRIG || HAVE_GSL
  11978. static mus_float_t ultraspherical(int n, mus_float_t x, mus_float_t lambda)
  11979. {
  11980. /* this is also the algorithm used in gsl gegenbauer.c -- slow but not as bad as using the binomials! */
  11981. mus_float_t fn1, fn2 = 1.0, fn = 1.0;
  11982. int k;
  11983. if (n == 0) return(1.0);
  11984. if (lambda == 0.0)
  11985. fn1 = 2.0 * x;
  11986. else fn1 = 2.0 * x * lambda;
  11987. if (n == 1) return(fn1);
  11988. for (k = 2; k <= n; k++)
  11989. {
  11990. fn = ((2.0 * x * (k + lambda - 1.0) * fn1) - ((k + (2.0 * lambda) - 2.0) * fn2)) / (mus_float_t)k;
  11991. fn2 = fn1;
  11992. fn1 = fn;
  11993. }
  11994. return(fn);
  11995. }
  11996. #endif
  11997. bool mus_is_fft_window(int val)
  11998. {
  11999. switch (val)
  12000. {
  12001. case MUS_RECTANGULAR_WINDOW: case MUS_HANN_WINDOW: case MUS_WELCH_WINDOW: case MUS_PARZEN_WINDOW:
  12002. case MUS_BARTLETT_WINDOW: case MUS_HAMMING_WINDOW: case MUS_BLACKMAN2_WINDOW: case MUS_BLACKMAN3_WINDOW:
  12003. case MUS_BLACKMAN4_WINDOW: case MUS_EXPONENTIAL_WINDOW: case MUS_RIEMANN_WINDOW: case MUS_KAISER_WINDOW:
  12004. case MUS_CAUCHY_WINDOW: case MUS_POISSON_WINDOW: case MUS_GAUSSIAN_WINDOW: case MUS_TUKEY_WINDOW:
  12005. case MUS_DOLPH_CHEBYSHEV_WINDOW: case MUS_HANN_POISSON_WINDOW: case MUS_CONNES_WINDOW:
  12006. case MUS_SAMARAKI_WINDOW: case MUS_ULTRASPHERICAL_WINDOW: case MUS_BARTLETT_HANN_WINDOW:
  12007. case MUS_BOHMAN_WINDOW: case MUS_FLAT_TOP_WINDOW: case MUS_BLACKMAN5_WINDOW: case MUS_BLACKMAN6_WINDOW:
  12008. case MUS_BLACKMAN7_WINDOW: case MUS_BLACKMAN8_WINDOW: case MUS_BLACKMAN9_WINDOW: case MUS_BLACKMAN10_WINDOW:
  12009. case MUS_RV2_WINDOW: case MUS_RV3_WINDOW: case MUS_RV4_WINDOW: case MUS_MLT_SINE_WINDOW:
  12010. case MUS_PAPOULIS_WINDOW: case MUS_DPSS_WINDOW: case MUS_SINC_WINDOW:
  12011. return(true);
  12012. break;
  12013. }
  12014. return(false);
  12015. }
  12016. #if HAVE_GSL
  12017. #include <gsl/gsl_version.h>
  12018. #if ((GSL_MAJOR_VERSION >= 1) && (GSL_MINOR_VERSION >= 9))
  12019. #include <gsl/gsl_math.h>
  12020. #include <gsl/gsl_eigen.h>
  12021. #define HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE 1
  12022. #endif
  12023. #endif
  12024. static mus_float_t sqr(mus_float_t x) {return(x * x);}
  12025. mus_float_t *mus_make_fft_window_with_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta, mus_float_t mu, mus_float_t *window)
  12026. {
  12027. /* mostly taken from
  12028. * Fredric J. Harris, "On the Use of Windows for Harmonic Analysis with the
  12029. * Discrete Fourier Transform," Proceedings of the IEEE, Vol. 66, No. 1,
  12030. * January 1978.
  12031. *
  12032. * Albert H. Nuttall, "Some Windows with Very Good Sidelobe Behaviour",
  12033. * IEEE Transactions of Acoustics, Speech, and Signal Processing, Vol. ASSP-29,
  12034. * No. 1, February 1981, pp 84-91
  12035. */
  12036. mus_long_t i, j, midn, midp1;
  12037. mus_float_t freq, rate, angle = 0.0, cx;
  12038. if (window == NULL) return(NULL);
  12039. midn = size >> 1;
  12040. midp1 = (size + 1) / 2;
  12041. freq = TWO_PI / (mus_float_t)size;
  12042. rate = 1.0 / (mus_float_t)midn;
  12043. switch (type)
  12044. {
  12045. case MUS_RECTANGULAR_WINDOW:
  12046. for (i = 0; i < size; i++)
  12047. window[i] = 1.0;
  12048. break;
  12049. case MUS_WELCH_WINDOW:
  12050. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12051. {
  12052. window[i] = 1.0 - sqr((mus_float_t)(i - midn) / (mus_float_t)midp1);
  12053. window[j] = window[i];
  12054. }
  12055. break;
  12056. case MUS_CONNES_WINDOW:
  12057. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12058. {
  12059. window[i] = sqr(1.0 - sqr((mus_float_t)(i - midn) / (mus_float_t)midp1));
  12060. window[j] = window[i];
  12061. }
  12062. break;
  12063. case MUS_PARZEN_WINDOW:
  12064. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12065. {
  12066. window[i] = 1.0 - fabs((mus_float_t)(i - midn) / (mus_float_t)midp1);
  12067. window[j] = window[i];
  12068. }
  12069. break;
  12070. case MUS_BARTLETT_WINDOW:
  12071. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += rate)
  12072. {
  12073. window[i] = angle;
  12074. window[j] = angle;
  12075. }
  12076. break;
  12077. case MUS_BARTLETT_HANN_WINDOW:
  12078. {
  12079. mus_float_t ramp;
  12080. rate *= 0.5;
  12081. /* this definition taken from mathworks docs: they use size - 1 throughout -- this makes very little
  12082. * difference unless you're using a small window. I decided to be consistent with all the other
  12083. * windows, and besides, this way actually peaks at 1.0 (which matlab misses)
  12084. */
  12085. for (i = 0, j = size - 1, angle = -M_PI, ramp = 0.5; i <= midn; i++, j--, angle += freq, ramp -= rate)
  12086. {
  12087. window[i] = 0.62 - 0.48 * ramp + 0.38 * cos(angle);
  12088. window[j] = window[i];
  12089. }
  12090. }
  12091. break;
  12092. case MUS_BOHMAN_WINDOW:
  12093. {
  12094. mus_float_t ramp;
  12095. /* definition from diracdelta docs and "DSP Handbook" -- used in bispectrum ("minimum bispectrum bias supremum") */
  12096. for (i = 0, j = size - 1, angle = M_PI, ramp = 0.0; i <= midn; i++, j--, angle -= freq, ramp += rate)
  12097. {
  12098. window[i] = ramp * cos(angle) + (sin(angle) / M_PI);
  12099. window[j] = window[i];
  12100. }
  12101. }
  12102. break;
  12103. case MUS_HANN_WINDOW:
  12104. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12105. {
  12106. window[i] = 0.5 - 0.5 * cos(angle);
  12107. window[j] = window[i];
  12108. }
  12109. break;
  12110. /* Rife-Vincent windows are an elaboration of this (Hann = RV1) */
  12111. case MUS_RV2_WINDOW:
  12112. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12113. {
  12114. window[i] = .375 - 0.5 * cos(angle) + .125 * cos(2 * angle);
  12115. window[j] = window[i];
  12116. }
  12117. break;
  12118. case MUS_RV3_WINDOW:
  12119. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12120. {
  12121. window[i] = (10.0 / 32.0) -
  12122. (15.0 / 32.0) * cos(angle) +
  12123. (6.0 / 32.0) * cos(2 * angle) -
  12124. (1.0 / 32.0) * cos(3 * angle);
  12125. window[j] = window[i];
  12126. }
  12127. break;
  12128. case MUS_RV4_WINDOW:
  12129. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12130. {
  12131. window[i] = (35.0 / 128.0) -
  12132. (56.0 / 128.0) * cos(angle) +
  12133. (28.0 / 128.0) * cos(2 * angle) -
  12134. (8.0 / 128.0) * cos(3 * angle) +
  12135. (1.0 / 128.0) * cos(4 * angle);
  12136. window[j] = window[i];
  12137. }
  12138. break;
  12139. case MUS_HAMMING_WINDOW:
  12140. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12141. {
  12142. window[i] = 0.54 - 0.46 * cos(angle);
  12143. window[j] = window[i];
  12144. }
  12145. break;
  12146. /* Blackman 1 is the same as Hamming */
  12147. case MUS_BLACKMAN2_WINDOW: /* using Chebyshev polynomial equivalents here (this is also given as .42 .5 .08) */
  12148. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12149. { /* (+ 0.42323 (* -0.49755 (cos a)) (* 0.07922 (cos (* a 2)))) */
  12150. /* "A Family...": .42438 .49341 .078279 */
  12151. cx = cos(angle);
  12152. window[i] = .34401 + (cx * (-.49755 + (cx * .15844)));
  12153. window[j] = window[i];
  12154. }
  12155. break;
  12156. case MUS_BLACKMAN3_WINDOW:
  12157. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12158. { /* (+ 0.35875 (* -0.48829 (cos a)) (* 0.14128 (cos (* a 2))) (* -0.01168 (cos (* a 3)))) */
  12159. /* (+ 0.36336 (* 0.48918 (cos a)) (* 0.13660 (cos (* a 2))) (* 0.01064 (cos (* a 3)))) is "Nuttall" window? */
  12160. /* "A Family...": .36358 .489177 .136599 .0106411 */
  12161. cx = cos(angle);
  12162. window[i] = .21747 + (cx * (-.45325 + (cx * (.28256 - (cx * .04672)))));
  12163. window[j] = window[i];
  12164. }
  12165. break;
  12166. case MUS_BLACKMAN4_WINDOW:
  12167. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12168. { /* (+ 0.287333 (* -0.44716 (cos a)) (* 0.20844 (cos (* a 2))) (* -0.05190 (cos (* a 3))) (* 0.005149 (cos (* a 4)))) */
  12169. /* "A Family...": .32321 .471492 .175534 .0284969 .001261357 */
  12170. cx = cos(angle);
  12171. window[i] = .084037 + (cx * (-.29145 + (cx * (.375696 + (cx * (-.20762 + (cx * .041194)))))));
  12172. window[j] = window[i];
  12173. }
  12174. break;
  12175. /* "A Family of Cosine-Sum Windows..." Albrecht */
  12176. case MUS_BLACKMAN5_WINDOW:
  12177. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12178. {
  12179. /* .293557 -.451935 .201416 -.047926 .00502619 -.000137555 */
  12180. /* partials->polynomial -> -0.196389809 -0.308844775 0.3626224697 -0.188952908 0.0402095206 -0.002200880, then fixup constant */
  12181. cx = cos(angle);
  12182. window[i] = 0.097167 +
  12183. (cx * (-.3088448 +
  12184. (cx * (.3626224 +
  12185. (cx * (-.1889530 +
  12186. (cx * (.04020952 +
  12187. (cx * -.0022008)))))))));
  12188. window[j] = window[i];
  12189. }
  12190. break;
  12191. case MUS_BLACKMAN6_WINDOW:
  12192. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12193. {
  12194. /* .2712203 -.4334446 .2180041 -.0657853 .010761867 -.0007700127 .00001368088 */
  12195. /* partials->polynomial -> -0.207255900 -0.239938736 0.3501594961
  12196. * -0.247740954 0.0854382589 -0.012320203 0.0004377882
  12197. */
  12198. cx = cos(angle);
  12199. window[i] = 0.063964353 +
  12200. (cx * (-0.239938736 +
  12201. (cx * (0.3501594961 +
  12202. (cx * (-0.247740954 +
  12203. (cx * (0.0854382589 +
  12204. (cx * (-0.012320203 +
  12205. (cx * 0.0004377882)))))))))));
  12206. window[j] = window[i];
  12207. }
  12208. break;
  12209. case MUS_BLACKMAN7_WINDOW:
  12210. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12211. {
  12212. /* .2533176 -.4163269 .2288396 -.08157508 .017735924 -.0020967027 .00010677413 -.0000012807 */
  12213. /* partials->polynomial -> -0.211210445 -0.182076216 0.3177137375 -0.284437984
  12214. * 0.1367622316 -0.033403806 0.0034167722 -0.000081965
  12215. */
  12216. cx = cos(angle);
  12217. window[i] = 0.04210723 +
  12218. (cx * (-0.18207621 +
  12219. (cx * (0.3177137375 +
  12220. (cx * (-0.284437984 +
  12221. (cx * (0.1367622316 +
  12222. (cx * (-0.033403806 +
  12223. (cx * (0.0034167722 +
  12224. (cx * -0.000081965)))))))))))));
  12225. window[j] = window[i];
  12226. }
  12227. break;
  12228. case MUS_BLACKMAN8_WINDOW:
  12229. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12230. {
  12231. /* .2384331 -.4005545 .2358242 -.09527918 .025373955 -.0041524329 .00036856041 -.00001384355 .0000001161808 */
  12232. /* partials->polynomial -> -0.210818693 -0.135382235 0.2752871215 -0.298843294 0.1853193194
  12233. * -0.064888448 0.0117641902 -0.000885987 0.0000148711
  12234. */
  12235. cx = cos(angle);
  12236. window[i] = 0.027614462 +
  12237. (cx * (-0.135382235 +
  12238. (cx * (0.2752871215 +
  12239. (cx * (-0.298843294 +
  12240. (cx * (0.1853193194 +
  12241. (cx * (-0.064888448 +
  12242. (cx * (0.0117641902 +
  12243. (cx * (-0.000885987 +
  12244. (cx * 0.0000148711)))))))))))))));
  12245. window[j] = window[i];
  12246. }
  12247. break;
  12248. case MUS_BLACKMAN9_WINDOW:
  12249. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12250. {
  12251. /* .2257345 -.3860122 .2401294 -.1070542 .03325916 -.00687337 .0008751673 -.0000600859 .000001710716 -.00000001027272 */
  12252. /* partials->polynomial -> -0.207743675 -0.098795950 0.2298837751 -0.294112951 0.2243389785
  12253. * -0.103248745 0.0275674108 -0.003839580 0.0002189716 -0.000002630
  12254. */
  12255. cx = cos(angle);
  12256. window[i] = 0.01799071953 +
  12257. (cx * (-0.098795950 +
  12258. (cx * (0.2298837751 +
  12259. (cx * (-0.294112951 +
  12260. (cx * (0.2243389785 +
  12261. (cx * (-0.103248745 +
  12262. (cx * (0.0275674108 +
  12263. (cx * (-0.003839580 +
  12264. (cx * (0.0002189716 +
  12265. (cx * -0.000002630)))))))))))))))));
  12266. window[j] = window[i];
  12267. }
  12268. break;
  12269. case MUS_BLACKMAN10_WINDOW:
  12270. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12271. {
  12272. /* .2151527 -.3731348 .2424243 -.1166907 .04077422 -.01000904 .0016398069 -.0001651660 .000008884663 -.000000193817 .00000000084824 */
  12273. /* partials->polynomial -> -0.203281015 -0.071953468 0.1878870875 -0.275808066
  12274. * 0.2489042133 -0.141729787 0.0502002984 -0.010458985 0.0011361511 -0.000049617 0.0000004343
  12275. */
  12276. cx = cos(angle);
  12277. window[i] = 0.0118717384 +
  12278. (cx * (-0.071953468 +
  12279. (cx * (0.1878870875 +
  12280. (cx * (-0.275808066 +
  12281. (cx * (0.2489042133 +
  12282. (cx * (-0.141729787 +
  12283. (cx * (0.0502002984 +
  12284. (cx * (-0.010458985 +
  12285. (cx * (0.0011361511 +
  12286. (cx * (-0.000049617 +
  12287. (cx * 0.0000004343)))))))))))))))))));
  12288. window[j] = window[i];
  12289. }
  12290. break;
  12291. case MUS_FLAT_TOP_WINDOW:
  12292. /* this definition taken from mathworks docs -- see above */
  12293. for (i = 0, j = size - 1, angle = 0.0; i <= midn; i++, j--, angle += freq)
  12294. {
  12295. window[i] = 0.2156 - 0.4160 * cos(angle) + 0.2781 * cos(2 * angle) - 0.0836 * cos(3 * angle) + 0.0069 * cos(4 * angle);
  12296. window[j] = window[i];
  12297. }
  12298. break;
  12299. case MUS_EXPONENTIAL_WINDOW:
  12300. {
  12301. mus_float_t expn, expsum = 1.0;
  12302. expn = log(2) / (mus_float_t)midn + 1.0;
  12303. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12304. {
  12305. window[i] = expsum - 1.0;
  12306. window[j] = window[i];
  12307. expsum *= expn;
  12308. }
  12309. }
  12310. break;
  12311. case MUS_KAISER_WINDOW:
  12312. {
  12313. mus_float_t I0beta;
  12314. I0beta = mus_bessi0(beta); /* Harris multiplies beta by pi */
  12315. for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate)
  12316. {
  12317. window[i] = mus_bessi0(beta * sqrt(1.0 - sqr(angle))) / I0beta;
  12318. window[j] = window[i];
  12319. }
  12320. }
  12321. break;
  12322. case MUS_CAUCHY_WINDOW:
  12323. for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate)
  12324. {
  12325. window[i] = 1.0 / (1.0 + sqr(beta * angle));
  12326. window[j] = window[i];
  12327. }
  12328. break;
  12329. case MUS_POISSON_WINDOW:
  12330. for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate)
  12331. {
  12332. window[i] = exp((-beta) * angle);
  12333. window[j] = window[i];
  12334. }
  12335. break;
  12336. case MUS_HANN_POISSON_WINDOW:
  12337. /* Hann * Poisson -- from JOS */
  12338. {
  12339. mus_float_t angle1;
  12340. for (i = 0, j = size - 1, angle = 1.0, angle1 = 0.0; i <= midn; i++, j--, angle -= rate, angle1 += freq)
  12341. {
  12342. window[i] = exp((-beta) * angle) * (0.5 - 0.5 * cos(angle1));
  12343. window[j] = window[i];
  12344. }
  12345. }
  12346. break;
  12347. case MUS_RIEMANN_WINDOW:
  12348. {
  12349. mus_float_t sr1;
  12350. sr1 = TWO_PI / (mus_float_t)size;
  12351. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12352. {
  12353. if (i == midn)
  12354. window[i] = 1.0;
  12355. else
  12356. {
  12357. cx = sr1 * (midn - i);
  12358. window[i] = sin(cx) / cx;
  12359. }
  12360. window[j] = window[i];
  12361. }
  12362. }
  12363. break;
  12364. case MUS_GAUSSIAN_WINDOW:
  12365. for (i = 0, j = size - 1, angle = 1.0; i <= midn; i++, j--, angle -= rate)
  12366. {
  12367. window[i] = exp(-.5 * sqr(beta * angle));
  12368. window[j] = window[i];
  12369. }
  12370. break;
  12371. case MUS_TUKEY_WINDOW:
  12372. cx = midn * (1.0 - beta);
  12373. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12374. {
  12375. if (i >= cx)
  12376. window[i] = 1.0;
  12377. else window[i] = .5 * (1.0 - cos(M_PI * i / cx));
  12378. window[j] = window[i];
  12379. }
  12380. break;
  12381. case MUS_MLT_SINE_WINDOW:
  12382. {
  12383. mus_float_t scl;
  12384. scl = M_PI / (mus_float_t)size;
  12385. for (i = 0, j = size - 1; i <= midn; i++, j--)
  12386. {
  12387. window[i] = sin((i + 0.5) * scl);
  12388. window[j] = window[i];
  12389. }
  12390. }
  12391. break;
  12392. case MUS_PAPOULIS_WINDOW:
  12393. {
  12394. int n2;
  12395. n2 = size / 2;
  12396. for (i = -n2; i < n2; i++)
  12397. {
  12398. mus_float_t ratio, pratio;
  12399. ratio = (mus_float_t)i / (mus_float_t)n2;
  12400. pratio = M_PI * ratio;
  12401. window[i + n2] = (fabs(sin(pratio)) / M_PI) + (cos(pratio) * (1.0 - fabs(ratio)));
  12402. }
  12403. }
  12404. break;
  12405. case MUS_SINC_WINDOW:
  12406. {
  12407. mus_float_t scl;
  12408. scl = 2 * M_PI / (size - 1);
  12409. for (i = -midn, j = 0; i < midn; i++, j++)
  12410. {
  12411. if (i == 0)
  12412. window[j] = 1.0;
  12413. else window[j] = sin(i * scl) / (i * scl);
  12414. }
  12415. }
  12416. break;
  12417. case MUS_DPSS_WINDOW:
  12418. #if HAVE_GSL_EIGEN_NONSYMMV_WORKSPACE
  12419. {
  12420. /* from Verma, Bilbao, Meng, "The Digital Prolate Spheroidal Window"
  12421. * output checked using Julius Smith's dpssw.m, although my "beta" is different
  12422. */
  12423. double *data; /* "double" for gsl func */
  12424. double cw, n1, pk = 0.0;
  12425. cw = cos(2 * M_PI * beta);
  12426. n1 = (size - 1) * 0.5;
  12427. if ((mus_long_t)(size * size * sizeof(double)) > mus_max_malloc())
  12428. {
  12429. mus_error(MUS_ARG_OUT_OF_RANGE, S_make_fft_window ": dpss window requires size^2 * 8 bytes, but that exceeds the current mus-max-malloc amount");
  12430. return(window);
  12431. }
  12432. data = (double *)calloc(size * size, sizeof(double));
  12433. for (i = 0; i < size; i++)
  12434. {
  12435. double n2;
  12436. n2 = n1 - i;
  12437. data[i * size + i] = cw * n2 * n2;
  12438. if (i < (size - 1))
  12439. data[i * (size + 1) + 1] = 0.5 * (i + 1) * (size - 1 - i);
  12440. if (i > 0)
  12441. data[i * (size + 1) - 1] = 0.5 * i * (size - i);
  12442. }
  12443. {
  12444. gsl_vector_complex_view evec_i;
  12445. gsl_matrix_view m = gsl_matrix_view_array(data, size, size);
  12446. gsl_vector_complex *eval = gsl_vector_complex_alloc(size);
  12447. gsl_matrix_complex *evec = gsl_matrix_complex_alloc(size, size);
  12448. gsl_eigen_nonsymmv_workspace *w = gsl_eigen_nonsymmv_alloc(size);
  12449. gsl_eigen_nonsymmv(&m.matrix, eval, evec, w);
  12450. gsl_eigen_nonsymmv_free(w);
  12451. gsl_eigen_nonsymmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
  12452. evec_i = gsl_matrix_complex_column(evec, 0);
  12453. for (j = 0; j < size; j++)
  12454. window[j] = GSL_REAL(gsl_vector_complex_get(&evec_i.vector, j));
  12455. gsl_vector_complex_free(eval);
  12456. gsl_matrix_complex_free(evec);
  12457. }
  12458. for (i = 0; i < size; i++)
  12459. if (fabs(window[i]) > fabs(pk))
  12460. pk = window[i];
  12461. if (pk != 0.0)
  12462. for (i = 0; i < size; i++)
  12463. window[i] /= pk;
  12464. free(data);
  12465. }
  12466. #else
  12467. mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": DPSS window needs GSL");
  12468. #endif
  12469. break;
  12470. case MUS_ULTRASPHERICAL_WINDOW:
  12471. case MUS_SAMARAKI_WINDOW:
  12472. case MUS_DOLPH_CHEBYSHEV_WINDOW:
  12473. /* "Design of Ultraspherical Window Functions with Prescribed Spectral Characteristics", Bergen and Antoniou, EURASIP JASP 2004 */
  12474. if (type == MUS_ULTRASPHERICAL_WINDOW)
  12475. {
  12476. if (mu == 0.0)
  12477. type = MUS_DOLPH_CHEBYSHEV_WINDOW;
  12478. else
  12479. {
  12480. if (mu == 1.0)
  12481. type = MUS_SAMARAKI_WINDOW;
  12482. }
  12483. }
  12484. #if HAVE_COMPLEX_TRIG
  12485. {
  12486. mus_float_t *rl, *im;
  12487. mus_float_t pk = 0.0;
  12488. mus_float_t alpha;
  12489. freq = M_PI / (mus_float_t)size;
  12490. if (beta < 0.2) beta = 0.2;
  12491. alpha = creal(ccosh(cacosh(pow(10.0, beta)) / (mus_float_t)size));
  12492. rl = (mus_float_t *)malloc(size * sizeof(mus_float_t));
  12493. im = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  12494. for (i = 0, angle = 0.0; i < size; i++, angle += freq)
  12495. {
  12496. switch (type)
  12497. {
  12498. case MUS_DOLPH_CHEBYSHEV_WINDOW:
  12499. rl[i] = creal(ccos(cacos(alpha * cos(angle)) * size)); /* here is Tn (Chebyshev polynomial first kind) */
  12500. break;
  12501. case MUS_SAMARAKI_WINDOW:
  12502. /* Samaraki window uses Un instead */
  12503. rl[i] = creal(csin(cacos(alpha * cos(angle)) * (size + 1.0)) / csin(cacos(alpha * cos(angle))));
  12504. break;
  12505. case MUS_ULTRASPHERICAL_WINDOW:
  12506. /* Cn here */
  12507. rl[i] = ultraspherical(size, alpha * cos(angle), mu);
  12508. break;
  12509. default:
  12510. break;
  12511. }
  12512. }
  12513. mus_fft(rl, im, size, -1); /* can be 1 here */
  12514. pk = 0.0;
  12515. for (i = 0; i < size; i++)
  12516. if (pk < rl[i])
  12517. pk = rl[i];
  12518. if ((pk != 0.0) && (pk != 1.0))
  12519. {
  12520. for (i = 0, j = size / 2; i < size; i++)
  12521. {
  12522. window[i] = rl[j++] / pk;
  12523. if (j == size) j = 0;
  12524. }
  12525. }
  12526. else
  12527. {
  12528. memcpy((void *)window, (void *)rl, size * sizeof(mus_float_t));
  12529. }
  12530. free(rl);
  12531. free(im);
  12532. }
  12533. #else
  12534. #if HAVE_GSL
  12535. {
  12536. mus_float_t *rl, *im;
  12537. mus_float_t pk;
  12538. mus_float_t alpha;
  12539. freq = M_PI / (mus_float_t)size;
  12540. if (beta < 0.2) beta = 0.2;
  12541. alpha = GSL_REAL(gsl_complex_cosh(
  12542. gsl_complex_mul_real(
  12543. gsl_complex_arccosh_real(pow(10.0, beta)),
  12544. (mus_float_t)(1.0 / (mus_float_t)size))));
  12545. rl = (mus_float_t *)malloc(size * sizeof(mus_float_t));
  12546. im = (mus_float_t *)calloc(size, sizeof(mus_float_t));
  12547. for (i = 0, angle = 0.0; i < size; i++, angle += freq)
  12548. {
  12549. switch (type)
  12550. {
  12551. case MUS_DOLPH_CHEBYSHEV_WINDOW:
  12552. rl[i] = GSL_REAL(gsl_complex_cos(
  12553. gsl_complex_mul_real(
  12554. gsl_complex_arccos_real(alpha * cos(angle)),
  12555. (mus_float_t)size)));
  12556. break;
  12557. case MUS_SAMARAKI_WINDOW:
  12558. rl[i] = GSL_REAL(gsl_complex_div(
  12559. gsl_complex_sin(
  12560. gsl_complex_mul_real(
  12561. gsl_complex_arccos_real(alpha * cos(angle)),
  12562. (mus_float_t)(size + 1.0))),
  12563. gsl_complex_sin(
  12564. gsl_complex_arccos_real(alpha * cos(angle)))));
  12565. break;
  12566. case MUS_ULTRASPHERICAL_WINDOW:
  12567. rl[i] = ultraspherical(size, alpha * cos(angle), mu);
  12568. break;
  12569. default:
  12570. break;
  12571. }
  12572. }
  12573. mus_fft(rl, im, size, -1); /* can be 1 here */
  12574. pk = 0.0;
  12575. for (i = 0; i < size; i++)
  12576. if (pk < rl[i])
  12577. pk = rl[i];
  12578. if ((pk != 0.0) && (pk != 1.0))
  12579. {
  12580. for (i = 0, j = size / 2; i < size; i++)
  12581. {
  12582. window[i] = rl[j++] / pk;
  12583. if (j == size) j = 0;
  12584. }
  12585. }
  12586. else
  12587. {
  12588. memcpy((void *)window, (void *)rl, size * sizeof(mus_float_t));
  12589. }
  12590. free(rl);
  12591. free(im);
  12592. }
  12593. #else
  12594. mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": Dolph-Chebyshev, Samaraki, and Ultraspherical windows need complex trig support");
  12595. #endif
  12596. #endif
  12597. break;
  12598. default:
  12599. mus_error(MUS_NO_SUCH_FFT_WINDOW, S_make_fft_window ": unknown fft data window: %d", (int)type);
  12600. break;
  12601. }
  12602. return(window);
  12603. }
  12604. mus_float_t *mus_make_fft_window(mus_fft_window_t type, mus_long_t size, mus_float_t beta)
  12605. {
  12606. return(mus_make_fft_window_with_window(type, size, beta, 0.0, (mus_float_t *)calloc(size, sizeof(mus_float_t))));
  12607. }
  12608. static const char *fft_window_names[MUS_NUM_FFT_WINDOWS] =
  12609. {"Rectangular", "Hann", "Welch", "Parzen", "Bartlett", "Hamming", "Blackman2", "Blackman3", "Blackman4",
  12610. "Exponential", "Riemann", "Kaiser", "Cauchy", "Poisson", "Gaussian", "Tukey", "Dolph-Chebyshev", "Hann-Poisson", "Connes",
  12611. "Samaraki", "Ultraspherical", "Bartlett-Hann", "Bohman", "Flat-top",
  12612. "Blackman5", "Blackman6", "Blackman7", "Blackman8", "Blackman9", "Blackman10",
  12613. "Rife-Vincent2", "Rife-Vincent3", "Rife-Vincent4", "MLT Sine", "Papoulis", "DPSS (Slepian)", "Sinc"
  12614. };
  12615. const char *mus_fft_window_name(mus_fft_window_t win)
  12616. {
  12617. if (mus_is_fft_window((int)win))
  12618. return(fft_window_names[(int)win]);
  12619. return("unknown");
  12620. }
  12621. const char **mus_fft_window_names(void)
  12622. {
  12623. return(fft_window_names);
  12624. }
  12625. mus_float_t *mus_spectrum(mus_float_t *rdat, mus_float_t *idat, mus_float_t *window, mus_long_t n, mus_spectrum_t type)
  12626. {
  12627. mus_long_t i;
  12628. mus_float_t maxa, lowest;
  12629. if (window)
  12630. {
  12631. for (i = 0; i < n; i++)
  12632. rdat[i] *= window[i];
  12633. }
  12634. memset((void *)idat, 0, n * sizeof(mus_float_t));
  12635. mus_fft(rdat, idat, n, 1);
  12636. lowest = 0.000001;
  12637. maxa = 0.0;
  12638. n = n / 2;
  12639. for (i = 0; i < n; i++)
  12640. {
  12641. mus_float_t val;
  12642. val = rdat[i] * rdat[i] + idat[i] * idat[i];
  12643. if (val < lowest)
  12644. rdat[i] = 0.001;
  12645. else
  12646. {
  12647. rdat[i] = sqrt(val);
  12648. if (rdat[i] > maxa) maxa = rdat[i];
  12649. }
  12650. }
  12651. if (maxa > 0.0)
  12652. {
  12653. maxa = 1.0 / maxa;
  12654. if (type == MUS_SPECTRUM_IN_DB)
  12655. {
  12656. mus_float_t todb;
  12657. todb = 20.0 / log(10.0);
  12658. for (i = 0; i < n; i++)
  12659. rdat[i] = todb * log(rdat[i] * maxa);
  12660. }
  12661. else
  12662. {
  12663. if (type == MUS_SPECTRUM_NORMALIZED)
  12664. for (i = 0; i < n; i++)
  12665. rdat[i] *= maxa;
  12666. }
  12667. }
  12668. return(rdat);
  12669. }
  12670. mus_float_t *mus_autocorrelate(mus_float_t *data, mus_long_t n)
  12671. {
  12672. mus_float_t *im;
  12673. mus_float_t fscl;
  12674. mus_long_t i, n2;
  12675. n2 = n / 2;
  12676. fscl = 1.0 / (mus_float_t)n;
  12677. im = (mus_float_t *)calloc(n, sizeof(mus_float_t));
  12678. mus_fft(data, im, n, 1);
  12679. for (i = 0; i < n; i++)
  12680. data[i] = data[i] * data[i] + im[i] * im[i];
  12681. memset((void *)im, 0, n * sizeof(mus_float_t));
  12682. mus_fft(data, im, n, -1);
  12683. for (i = 0; i <= n2; i++)
  12684. data[i] *= fscl;
  12685. for (i = n2 + 1; i < n; i++)
  12686. data[i] = 0.0;
  12687. free(im);
  12688. return(data);
  12689. }
  12690. mus_float_t *mus_correlate(mus_float_t *data1, mus_float_t *data2, mus_long_t n)
  12691. {
  12692. mus_float_t *im1, *im2;
  12693. mus_long_t i;
  12694. mus_float_t fscl;
  12695. im1 = (mus_float_t *)calloc(n, sizeof(mus_float_t));
  12696. im2 = (mus_float_t *)calloc(n, sizeof(mus_float_t));
  12697. mus_fft(data1, im1, n, 1);
  12698. mus_fft(data2, im2, n, 1);
  12699. for (i = 0; i < n; i++)
  12700. {
  12701. mus_float_t tmp1, tmp2, tmp3, tmp4;
  12702. tmp1 = data1[i] * data2[i];
  12703. tmp2 = im1[i] * im2[i];
  12704. tmp3 = data1[i] * im2[i];
  12705. tmp4 = data2[i] * im1[i];
  12706. data1[i] = tmp1 + tmp2;
  12707. im1[i] = tmp3 - tmp4;
  12708. }
  12709. mus_fft(data1, im1, n, -1);
  12710. fscl = 1.0 / (mus_float_t)n;
  12711. for (i = 0; i < n; i++)
  12712. data1[i] *= fscl;
  12713. free(im1);
  12714. free(im2);
  12715. return(data1);
  12716. }
  12717. mus_float_t *mus_cepstrum(mus_float_t *data, mus_long_t n)
  12718. {
  12719. mus_float_t *rl, *im;
  12720. mus_float_t fscl, lowest;
  12721. mus_long_t i;
  12722. lowest = 0.00000001;
  12723. fscl = 2.0 / (mus_float_t)n;
  12724. rl = (mus_float_t *)malloc(n * sizeof(mus_float_t));
  12725. im = (mus_float_t *)calloc(n, sizeof(mus_float_t));
  12726. memcpy((void *)rl, (void *)data, n * sizeof(mus_float_t));
  12727. mus_fft(rl, im, n, 1);
  12728. for (i = 0; i < n; i++)
  12729. {
  12730. rl[i] = rl[i] * rl[i] + im[i] * im[i];
  12731. if (rl[i] < lowest)
  12732. rl[i] = -10.0;
  12733. else rl[i] = log(sqrt(rl[i]));
  12734. }
  12735. memset((void *)im, 0, n * sizeof(mus_float_t));
  12736. mus_fft(rl, im, n, -1);
  12737. for (i = 0; i < n; i++)
  12738. if (fabs(rl[i]) > fscl)
  12739. fscl = fabs(rl[i]);
  12740. if (fscl > 0.0)
  12741. for (i = 0; i < n; i++)
  12742. data[i] = rl[i] / fscl;
  12743. free(rl);
  12744. free(im);
  12745. return(data);
  12746. }
  12747. /* ---------------- convolve ---------------- */
  12748. mus_float_t *mus_convolution(mus_float_t *rl1, mus_float_t *rl2, mus_long_t n)
  12749. {
  12750. /* convolves two real arrays.
  12751. * rl1 and rl2 are assumed to be set up correctly for the convolution
  12752. * (that is, rl1 (the "signal") is zero-padded by length of
  12753. * (non-zero part of) rl2 and rl2 is stored in wrap-around order)
  12754. * We treat rl2 as the imaginary part of the first fft, then do
  12755. * the split, scaling, and (complex) spectral multiply in one step.
  12756. * result in rl1
  12757. */
  12758. mus_long_t j, n2;
  12759. mus_float_t invn;
  12760. mus_fft(rl1, rl2, n, 1);
  12761. n2 = n >> 1;
  12762. invn = 0.25 / (mus_float_t)n;
  12763. rl1[0] = ((rl1[0] * rl2[0]) / (mus_float_t)n);
  12764. rl2[0] = 0.0;
  12765. for (j = 1; j <= n2; j++)
  12766. {
  12767. mus_long_t nn2;
  12768. mus_float_t rem, rep, aim, aip;
  12769. nn2 = n - j;
  12770. rep = (rl1[j] + rl1[nn2]);
  12771. rem = (rl1[j] - rl1[nn2]);
  12772. aip = (rl2[j] + rl2[nn2]);
  12773. aim = (rl2[j] - rl2[nn2]);
  12774. rl1[j] = invn * (rep * aip + aim * rem);
  12775. rl2[j] = invn * (aim * aip - rep * rem);
  12776. rl1[nn2] = rl1[j];
  12777. rl2[nn2] = -rl2[j];
  12778. }
  12779. mus_fft(rl1, rl2, n, -1);
  12780. return(rl1);
  12781. }
  12782. typedef struct {
  12783. mus_any_class *core;
  12784. mus_float_t (*feeder)(void *arg, int direction);
  12785. mus_float_t (*block_feeder)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end);
  12786. mus_long_t fftsize, fftsize2, ctr, filtersize;
  12787. mus_float_t *rl1, *rl2, *buf, *filter;
  12788. void *closure;
  12789. } conv;
  12790. static bool convolve_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  12791. static char *describe_convolve(mus_any *ptr)
  12792. {
  12793. conv *gen = (conv *)ptr;
  12794. char *describe_buffer;
  12795. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  12796. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s size: %lld",
  12797. mus_name(ptr),
  12798. gen->fftsize);
  12799. return(describe_buffer);
  12800. }
  12801. static void free_convolve(mus_any *ptr)
  12802. {
  12803. conv *gen = (conv *)ptr;
  12804. if (gen->rl1) free(gen->rl1);
  12805. if (gen->rl2) free(gen->rl2);
  12806. if (gen->buf) free(gen->buf);
  12807. free(gen);
  12808. }
  12809. static mus_any *conv_copy(mus_any *ptr)
  12810. {
  12811. conv *g, *p;
  12812. int bytes;
  12813. p = (conv *)ptr;
  12814. g = (conv *)malloc(sizeof(conv));
  12815. memcpy((void *)g, (void *)ptr, sizeof(conv));
  12816. bytes = g->fftsize * sizeof(mus_float_t);
  12817. g->rl1 = (mus_float_t *)malloc(bytes);
  12818. memcpy((void *)(g->rl1), (void *)(p->rl1), bytes);
  12819. g->rl2 = (mus_float_t *)malloc(bytes);
  12820. memcpy((void *)(g->rl2), (void *)(p->rl2), bytes);
  12821. g->buf = (mus_float_t *)malloc(bytes);
  12822. memcpy((void *)(g->buf), (void *)(p->buf), bytes);
  12823. return((mus_any *)g);
  12824. }
  12825. static mus_long_t conv_length(mus_any *ptr) {return(((conv *)ptr)->fftsize);}
  12826. static mus_float_t run_convolve(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_convolve(ptr, NULL));}
  12827. static void *conv_closure(mus_any *rd) {return(((conv *)rd)->closure);}
  12828. static void *conv_set_closure(mus_any *rd, void *e) {((conv *)rd)->closure = e; return(e);}
  12829. static void convolve_reset(mus_any *ptr)
  12830. {
  12831. conv *gen = (conv *)ptr;
  12832. gen->ctr = gen->fftsize2;
  12833. memset((void *)(gen->rl1), 0, gen->fftsize * sizeof(mus_float_t));
  12834. memset((void *)(gen->rl2), 0, gen->fftsize * sizeof(mus_float_t));
  12835. memset((void *)(gen->buf), 0, gen->fftsize * sizeof(mus_float_t));
  12836. }
  12837. static mus_any_class CONVOLVE_CLASS = {
  12838. MUS_CONVOLVE,
  12839. (char *)S_convolve,
  12840. &free_convolve,
  12841. &describe_convolve,
  12842. &convolve_equalp,
  12843. 0, 0,
  12844. &conv_length,
  12845. 0,
  12846. 0, 0, 0, 0,
  12847. 0, 0,
  12848. 0, 0,
  12849. &run_convolve,
  12850. MUS_NOT_SPECIAL,
  12851. &conv_closure,
  12852. 0,
  12853. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  12854. 0, 0, 0, 0, 0, 0, 0,
  12855. 0, 0, 0, 0,
  12856. &convolve_reset,
  12857. &conv_set_closure,
  12858. &conv_copy
  12859. };
  12860. mus_float_t mus_convolve(mus_any *ptr, mus_float_t (*input)(void *arg, int direction))
  12861. {
  12862. conv *gen = (conv *)ptr;
  12863. mus_float_t result;
  12864. if (gen->ctr >= gen->fftsize2)
  12865. {
  12866. mus_long_t i, N;
  12867. size_t bytes;
  12868. N = gen->fftsize2;
  12869. bytes = N * sizeof(mus_float_t);
  12870. if (input) {gen->feeder = input; gen->block_feeder = NULL;}
  12871. memset((void *)(gen->rl2), 0, bytes * 2);
  12872. memcpy((void *)(gen->rl2), (void *)(gen->filter), gen->filtersize * sizeof(mus_float_t));
  12873. memcpy((void *)(gen->buf), (void *)(gen->buf + N), bytes);
  12874. memset((void *)(gen->buf + N), 0, bytes);
  12875. memset((void *)(gen->rl1 + N), 0, bytes);
  12876. if (gen->block_feeder)
  12877. gen->block_feeder(gen->closure, 1, gen->rl1, 0, N);
  12878. else
  12879. {
  12880. for (i = 0; i < N;)
  12881. {
  12882. gen->rl1[i] = gen->feeder(gen->closure, 1); i++;
  12883. gen->rl1[i] = gen->feeder(gen->closure, 1); i++;
  12884. }
  12885. }
  12886. mus_convolution(gen->rl1, gen->rl2, gen->fftsize);
  12887. for (i = 0; i < N;)
  12888. {
  12889. gen->buf[i] += gen->rl1[i]; i++;
  12890. gen->buf[i] += gen->rl1[i]; i++;
  12891. }
  12892. memcpy((void *)(gen->buf + N), (void *)(gen->rl1 + N), bytes);
  12893. gen->ctr = 0;
  12894. }
  12895. result = gen->buf[gen->ctr];
  12896. gen->ctr++;
  12897. return(result);
  12898. }
  12899. bool mus_is_convolve(mus_any *ptr)
  12900. {
  12901. return((ptr) &&
  12902. (ptr->core->type == MUS_CONVOLVE));
  12903. }
  12904. mus_any *mus_make_convolve(mus_float_t (*input)(void *arg, int direction), mus_float_t *filter, mus_long_t fftsize, mus_long_t filtersize, void *closure)
  12905. {
  12906. conv *gen = NULL;
  12907. gen = (conv *)malloc(sizeof(conv));
  12908. gen->core = &CONVOLVE_CLASS;
  12909. gen->feeder = input;
  12910. gen->block_feeder = NULL;
  12911. gen->closure = closure;
  12912. gen->filter = filter;
  12913. if (filter)
  12914. {
  12915. mus_long_t i;
  12916. bool all_zero = true;
  12917. for (i = 0; i < filtersize; i++)
  12918. if (fabs(filter[i]) != 0.0) /* I'm getting -0.000 != 0.000 */
  12919. {
  12920. all_zero = false;
  12921. break;
  12922. }
  12923. if (all_zero)
  12924. mus_print("make_convolve: filter contains only 0.0.");
  12925. }
  12926. gen->filtersize = filtersize;
  12927. gen->fftsize = fftsize;
  12928. gen->fftsize2 = gen->fftsize / 2;
  12929. gen->ctr = gen->fftsize2;
  12930. gen->rl1 = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  12931. gen->rl2 = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  12932. gen->buf = (mus_float_t *)calloc(fftsize, sizeof(mus_float_t));
  12933. return((mus_any *)gen);
  12934. }
  12935. void mus_convolve_files(const char *file1, const char *file2, mus_float_t maxamp, const char *output_file)
  12936. {
  12937. mus_long_t file1_len, file2_len, outlen, totallen;
  12938. int file1_chans, file2_chans, output_chans;
  12939. mus_float_t *data1, *data2;
  12940. const char *errmsg = NULL;
  12941. mus_float_t maxval = 0.0;
  12942. mus_long_t i, fftlen;
  12943. file1_len = mus_sound_framples(file1);
  12944. file2_len = mus_sound_framples(file2);
  12945. if ((file1_len <= 0) || (file2_len <= 0)) return;
  12946. file1_chans = mus_sound_chans(file1);
  12947. if (file1_chans <= 0) mus_error(MUS_NO_CHANNELS, S_convolve_files ": %s chans: %d", file1, file1_chans);
  12948. file2_chans = mus_sound_chans(file2);
  12949. if (file2_chans <= 0) mus_error(MUS_NO_CHANNELS, S_convolve_files ": %s chans: %d", file2, file2_chans);
  12950. output_chans = file1_chans;
  12951. if (file2_chans > output_chans) output_chans = file2_chans;
  12952. fftlen = (mus_long_t)(pow(2.0, (int)ceil(log(file1_len + file2_len + 1) / log(2.0))));
  12953. outlen = file1_len + file2_len + 1;
  12954. totallen = outlen * output_chans;
  12955. data1 = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t));
  12956. data2 = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t));
  12957. if (output_chans == 1)
  12958. {
  12959. mus_float_t *samps;
  12960. samps = (mus_float_t *)calloc(fftlen, sizeof(mus_float_t));
  12961. mus_file_to_array(file1, 0, 0, file1_len, samps);
  12962. for (i = 0; i < file1_len; i++) data1[i] = samps[i];
  12963. mus_file_to_array(file2, 0, 0, file2_len, samps);
  12964. for (i = 0; i < file2_len; i++) data2[i] = samps[i];
  12965. mus_convolution(data1, data2, fftlen);
  12966. for (i = 0; i < outlen; i++)
  12967. if (maxval < fabs(data1[i]))
  12968. maxval = fabs(data1[i]);
  12969. if (maxval > 0.0)
  12970. {
  12971. maxval = maxamp / maxval;
  12972. for (i = 0; i < outlen; i++) data1[i] *= maxval;
  12973. }
  12974. for (i = 0; i < outlen; i++) samps[i] = data1[i];
  12975. errmsg = mus_array_to_file_with_error(output_file, samps, outlen, mus_sound_srate(file1), 1);
  12976. free(samps);
  12977. }
  12978. else
  12979. {
  12980. mus_float_t *samps;
  12981. mus_float_t *outdat = NULL;
  12982. int c1 = 0, c2 = 0, chan;
  12983. samps = (mus_float_t *)calloc(totallen, sizeof(mus_float_t));
  12984. outdat = (mus_float_t *)malloc(totallen * sizeof(mus_float_t));
  12985. for (chan = 0; chan < output_chans; chan++)
  12986. {
  12987. mus_long_t j, k;
  12988. mus_file_to_array(file1, c1, 0, file1_len, samps);
  12989. for (k = 0; k < file1_len; k++) data1[k] = samps[k];
  12990. mus_file_to_array(file2, c2, 0, file2_len, samps);
  12991. for (k = 0; k < file2_len; k++) data2[k] = samps[k];
  12992. mus_convolution(data1, data2, fftlen);
  12993. for (j = chan, k = 0; j < totallen; j += output_chans, k++) outdat[j] = data1[k];
  12994. c1++;
  12995. if (c1 >= file1_chans) c1 = 0;
  12996. c2++;
  12997. if (c2 >= file2_chans) c2 = 0;
  12998. memset((void *)data1, 0, fftlen * sizeof(mus_float_t));
  12999. memset((void *)data2, 0, fftlen * sizeof(mus_float_t));
  13000. }
  13001. for (i = 0; i < totallen; i++)
  13002. if (maxval < fabs(outdat[i]))
  13003. maxval = fabs(outdat[i]);
  13004. if (maxval > 0.0)
  13005. {
  13006. maxval = maxamp / maxval;
  13007. for (i = 0; i < totallen; i++) outdat[i] *= maxval;
  13008. }
  13009. for (i = 0; i < totallen; i++)
  13010. samps[i] = outdat[i];
  13011. errmsg = mus_array_to_file_with_error(output_file, samps, totallen, mus_sound_srate(file1), output_chans);
  13012. free(samps);
  13013. free(outdat);
  13014. }
  13015. free(data1);
  13016. free(data2);
  13017. if (errmsg)
  13018. mus_error(MUS_CANT_OPEN_FILE, S_convolve_files ": %s", errmsg);
  13019. }
  13020. /* ---------------- phase-vocoder ---------------- */
  13021. typedef struct {
  13022. mus_any_class *core;
  13023. mus_float_t pitch;
  13024. mus_float_t (*input)(void *arg, int direction);
  13025. mus_float_t (*block_input)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end);
  13026. void *closure;
  13027. bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction));
  13028. int (*edit)(void *arg);
  13029. mus_float_t (*synthesize)(void *arg);
  13030. int outctr, interp, filptr, N, D, topN;
  13031. mus_float_t *win, *ampinc, *amps, *freqs, *phases, *phaseinc, *lastphase, *in_data;
  13032. mus_float_t sum1;
  13033. bool calc;
  13034. #if HAVE_SINCOS
  13035. double *cs, *sn;
  13036. bool *sc_safe;
  13037. int *indices;
  13038. #endif
  13039. } pv_info;
  13040. bool mus_is_phase_vocoder(mus_any *ptr)
  13041. {
  13042. return((ptr) &&
  13043. (ptr->core->type == MUS_PHASE_VOCODER));
  13044. }
  13045. static bool phase_vocoder_equalp(mus_any *p1, mus_any *p2) {return(p1 == p2);}
  13046. static char *describe_phase_vocoder(mus_any *ptr)
  13047. {
  13048. char *arr = NULL;
  13049. pv_info *gen = (pv_info *)ptr;
  13050. char *describe_buffer;
  13051. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  13052. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s outctr: %d, interp: %d, filptr: %d, N: %d, D: %d, in_data: %s",
  13053. mus_name(ptr),
  13054. gen->outctr, gen->interp, gen->filptr, gen->N, gen->D,
  13055. arr = float_array_to_string(gen->in_data, gen->N, 0));
  13056. if (arr) free(arr);
  13057. return(describe_buffer);
  13058. }
  13059. static void free_phase_vocoder(mus_any *ptr)
  13060. {
  13061. pv_info *gen = (pv_info *)ptr;
  13062. if (gen->in_data) free(gen->in_data);
  13063. if (gen->amps) free(gen->amps);
  13064. if (gen->freqs) free(gen->freqs);
  13065. if (gen->phases) free(gen->phases);
  13066. if (gen->win) free(gen->win);
  13067. if (gen->phaseinc) free(gen->phaseinc);
  13068. if (gen->lastphase) free(gen->lastphase);
  13069. if (gen->ampinc) free(gen->ampinc);
  13070. #if HAVE_SINCOS
  13071. if (gen->indices) free(gen->indices);
  13072. if (gen->sn) free(gen->sn);
  13073. if (gen->cs) free(gen->cs);
  13074. if (gen->sc_safe) free(gen->sc_safe);
  13075. #endif
  13076. free(gen);
  13077. }
  13078. static mus_any *pv_info_copy(mus_any *ptr)
  13079. {
  13080. pv_info *g, *p;
  13081. int bytes;
  13082. p = (pv_info *)ptr;
  13083. g = (pv_info *)malloc(sizeof(pv_info));
  13084. memcpy((void *)g, (void *)ptr, sizeof(pv_info));
  13085. bytes = p->N * sizeof(mus_float_t);
  13086. g->freqs = (mus_float_t *)malloc(bytes);
  13087. memcpy((void *)(g->freqs), (void *)(p->freqs), bytes);
  13088. g->ampinc = (mus_float_t *)malloc(bytes);
  13089. memcpy((void *)(g->ampinc), (void *)(p->ampinc), bytes);
  13090. g->win = (mus_float_t *)malloc(bytes);
  13091. memcpy((void *)(g->win), (void *)(p->win), bytes);
  13092. if (p->in_data)
  13093. {
  13094. g->in_data = (mus_float_t *)malloc(bytes);
  13095. memcpy((void *)(g->in_data), (void *)(p->in_data), bytes);
  13096. }
  13097. bytes = (p->N / 2) * sizeof(mus_float_t);
  13098. g->amps = (mus_float_t *)malloc(bytes);
  13099. memcpy((void *)(g->amps), (void *)(p->amps), bytes);
  13100. g->phases = (mus_float_t *)malloc(bytes);
  13101. memcpy((void *)(g->phases), (void *)(p->phases), bytes);
  13102. g->lastphase = (mus_float_t *)malloc(bytes);
  13103. memcpy((void *)(g->lastphase), (void *)(p->lastphase), bytes);
  13104. g->phaseinc = (mus_float_t *)malloc(bytes);
  13105. memcpy((void *)(g->phaseinc), (void *)(p->phaseinc), bytes);
  13106. #if HAVE_SINCOS
  13107. bytes = (p->N / 2) * sizeof(int);
  13108. g->indices = (int *)malloc(bytes);
  13109. memcpy((void *)(g->indices), (void *)(p->indices), bytes);
  13110. bytes = p->N * sizeof(double);
  13111. g->sn = (double *)malloc(bytes);
  13112. memcpy((void *)(g->sn), (void *)(p->sn), bytes);
  13113. g->cs = (double *)malloc(bytes);
  13114. memcpy((void *)(g->cs), (void *)(p->cs), bytes);
  13115. bytes = p->N * sizeof(bool);
  13116. g->sc_safe = (bool *)malloc(bytes);
  13117. memcpy((void *)(g->sc_safe), (void *)(p->sc_safe), bytes);
  13118. #endif
  13119. return((mus_any *)g);
  13120. }
  13121. static mus_long_t pv_length(mus_any *ptr) {return(((pv_info *)ptr)->N);}
  13122. static mus_long_t pv_hop(mus_any *ptr) {return(((pv_info *)ptr)->D);}
  13123. static mus_long_t pv_set_hop(mus_any *ptr, mus_long_t val) {((pv_info *)ptr)->D = (int)val; return(val);}
  13124. static mus_float_t pv_frequency(mus_any *ptr) {return(((pv_info *)ptr)->pitch);}
  13125. static mus_float_t pv_set_frequency(mus_any *ptr, mus_float_t val) {((pv_info *)ptr)->pitch = val; return(val);}
  13126. static void *pv_closure(mus_any *rd) {return(((pv_info *)rd)->closure);}
  13127. static void *pv_set_closure(mus_any *rd, void *e) {((pv_info *)rd)->closure = e; return(e);}
  13128. mus_float_t *mus_phase_vocoder_amp_increments(mus_any *ptr) {return(((pv_info *)ptr)->ampinc);}
  13129. mus_float_t *mus_phase_vocoder_amps(mus_any *ptr) {return(((pv_info *)ptr)->amps);}
  13130. mus_float_t *mus_phase_vocoder_freqs(mus_any *ptr) {return(((pv_info *)ptr)->freqs);}
  13131. mus_float_t *mus_phase_vocoder_phases(mus_any *ptr) {return(((pv_info *)ptr)->phases);}
  13132. mus_float_t *mus_phase_vocoder_phase_increments(mus_any *ptr) {return(((pv_info *)ptr)->phaseinc);}
  13133. static mus_long_t pv_outctr(mus_any *ptr) {return((mus_long_t)(((pv_info *)ptr)->outctr));} /* mus_location wrapper */
  13134. static mus_long_t pv_set_outctr(mus_any *ptr, mus_long_t val) {((pv_info *)ptr)->outctr = (int)val; return(val);}
  13135. static mus_float_t run_phase_vocoder(mus_any *ptr, mus_float_t unused1, mus_float_t unused2) {return(mus_phase_vocoder(ptr, NULL));}
  13136. static mus_float_t pv_increment(mus_any *rd) {return((mus_float_t)(((pv_info *)rd)->interp));}
  13137. static mus_float_t pv_set_increment(mus_any *rd, mus_float_t val) {((pv_info *)rd)->interp = (int)val; return(val);}
  13138. static void pv_reset(mus_any *ptr)
  13139. {
  13140. pv_info *gen = (pv_info *)ptr;
  13141. if (gen->in_data) free(gen->in_data);
  13142. gen->in_data = NULL;
  13143. gen->outctr = gen->interp;
  13144. gen->filptr = 0;
  13145. memset((void *)(gen->ampinc), 0, gen->N * sizeof(mus_float_t));
  13146. memset((void *)(gen->freqs), 0, gen->N * sizeof(mus_float_t));
  13147. memset((void *)(gen->amps), 0, (gen->N / 2) * sizeof(mus_float_t));
  13148. memset((void *)(gen->phases), 0, (gen->N / 2) * sizeof(mus_float_t));
  13149. memset((void *)(gen->lastphase), 0, (gen->N / 2) * sizeof(mus_float_t));
  13150. memset((void *)(gen->phaseinc), 0, (gen->N / 2) * sizeof(mus_float_t));
  13151. }
  13152. static mus_any_class PHASE_VOCODER_CLASS = {
  13153. MUS_PHASE_VOCODER,
  13154. (char *)S_phase_vocoder,
  13155. &free_phase_vocoder,
  13156. &describe_phase_vocoder,
  13157. &phase_vocoder_equalp,
  13158. 0, 0,
  13159. &pv_length, 0,
  13160. &pv_frequency,
  13161. &pv_set_frequency,
  13162. 0, 0,
  13163. 0, 0,
  13164. &pv_increment,
  13165. &pv_set_increment,
  13166. &run_phase_vocoder,
  13167. MUS_NOT_SPECIAL,
  13168. &pv_closure,
  13169. 0,
  13170. 0, 0, 0, 0, 0, 0,
  13171. &pv_hop, &pv_set_hop,
  13172. 0, 0,
  13173. 0, 0, 0, 0,
  13174. &pv_outctr, &pv_set_outctr,
  13175. 0, 0, 0, 0, 0,
  13176. &pv_reset,
  13177. &pv_set_closure,
  13178. &pv_info_copy
  13179. };
  13180. static int pv_last_fftsize = -1;
  13181. static mus_float_t *pv_last_window = NULL;
  13182. mus_any *mus_make_phase_vocoder(mus_float_t (*input)(void *arg, int direction),
  13183. int fftsize, int overlap, int interp,
  13184. mus_float_t pitch,
  13185. bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)),
  13186. int (*edit)(void *arg),
  13187. mus_float_t (*synthesize)(void *arg),
  13188. void *closure)
  13189. {
  13190. /* order of args is trying to match src, granulate etc
  13191. * the inclusion of pitch and interp provides built-in time/pitch scaling which is 99% of phase-vocoder use
  13192. */
  13193. pv_info *pv;
  13194. int N2, D;
  13195. N2 = (int)(fftsize / 2);
  13196. if (N2 == 0) return(NULL);
  13197. D = fftsize / overlap;
  13198. if (D == 0) return(NULL);
  13199. pv = (pv_info *)malloc(sizeof(pv_info));
  13200. pv->core = &PHASE_VOCODER_CLASS;
  13201. pv->N = fftsize;
  13202. pv->D = D;
  13203. pv->topN = 0;
  13204. pv->interp = interp;
  13205. pv->outctr = interp;
  13206. pv->filptr = 0;
  13207. pv->pitch = pitch;
  13208. pv->ampinc = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  13209. pv->freqs = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  13210. pv->amps = (mus_float_t *)calloc(N2, sizeof(mus_float_t));
  13211. pv->phases = (mus_float_t *)calloc(N2, sizeof(mus_float_t));
  13212. pv->lastphase = (mus_float_t *)calloc(N2, sizeof(mus_float_t));
  13213. pv->phaseinc = (mus_float_t *)calloc(N2, sizeof(mus_float_t));
  13214. pv->in_data = NULL;
  13215. pv->input = input;
  13216. pv->block_input = NULL;
  13217. pv->closure = closure;
  13218. pv->analyze = analyze;
  13219. pv->edit = edit;
  13220. pv->synthesize = synthesize;
  13221. pv->calc = true;
  13222. if ((fftsize == pv_last_fftsize) && (pv_last_window))
  13223. {
  13224. pv->win = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  13225. memcpy((void *)(pv->win), (const void *)pv_last_window, fftsize * sizeof(mus_float_t));
  13226. }
  13227. else
  13228. {
  13229. int i;
  13230. mus_float_t scl;
  13231. if (pv_last_window) free(pv_last_window);
  13232. pv_last_fftsize = fftsize;
  13233. pv_last_window = (mus_float_t *)malloc(fftsize * sizeof(mus_float_t));
  13234. pv->win = mus_make_fft_window(MUS_HAMMING_WINDOW, fftsize, 0.0);
  13235. scl = 2.0 / (0.54 * (mus_float_t)fftsize);
  13236. for (i = 0; i < fftsize; i++)
  13237. pv->win[i] *= scl;
  13238. memcpy((void *)pv_last_window, (const void *)(pv->win), fftsize * sizeof(mus_float_t));
  13239. }
  13240. #if HAVE_SINCOS
  13241. /* in some cases, sincos is slower than sin+cos? Callgrind is seriously confused by it!
  13242. * in Linux at least, sincos is faster than sin+sin -- in my timing tests, although
  13243. * callgrind is crazy, the actual runtimes are about 25% faster (sincos vs sin+sin).
  13244. */
  13245. pv->cs = (double *)malloc(fftsize * sizeof(double));
  13246. pv->sn = (double *)malloc(fftsize * sizeof(double));
  13247. pv->sc_safe = (bool *)calloc(fftsize, sizeof(bool));
  13248. pv->indices = (int *)malloc(N2 * sizeof(int));
  13249. #endif
  13250. return((mus_any *)pv);
  13251. }
  13252. mus_float_t mus_phase_vocoder_with_editors(mus_any *ptr,
  13253. mus_float_t (*input)(void *arg, int direction),
  13254. bool (*analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)),
  13255. int (*edit)(void *arg),
  13256. mus_float_t (*synthesize)(void *arg))
  13257. {
  13258. pv_info *pv = (pv_info *)ptr;
  13259. int N2, i;
  13260. mus_float_t sum, sum1;
  13261. mus_float_t (*pv_synthesize)(void *arg) = synthesize;
  13262. if (pv_synthesize == NULL) pv_synthesize = pv->synthesize;
  13263. N2 = pv->N / 2;
  13264. if (pv->outctr >= pv->interp)
  13265. {
  13266. mus_float_t scl;
  13267. bool (*pv_analyze)(void *arg, mus_float_t (*input)(void *arg1, int direction)) = analyze;
  13268. int (*pv_edit)(void *arg) = edit;
  13269. if (pv_analyze == NULL) pv_analyze = pv->analyze;
  13270. if (pv_edit == NULL) pv_edit = pv->edit;
  13271. if (input) {pv->input = input; pv->block_input = NULL;}
  13272. pv->outctr = 0;
  13273. if ((pv_analyze == NULL) ||
  13274. ((*pv_analyze)(pv->closure, pv->input)))
  13275. {
  13276. int buf;
  13277. memset((void *)(pv->freqs), 0, pv->N * sizeof(mus_float_t));
  13278. if (pv->in_data == NULL)
  13279. {
  13280. pv->in_data = (mus_float_t *)malloc(pv->N * sizeof(mus_float_t));
  13281. if (pv->block_input)
  13282. pv->block_input(pv->closure, 1, pv->in_data, 0, pv->N);
  13283. else
  13284. {
  13285. for (i = 0; i < pv->N; i++)
  13286. pv->in_data[i] = pv->input(pv->closure, 1);
  13287. }
  13288. }
  13289. else
  13290. {
  13291. int j;
  13292. /* if back-to-back here we could omit a lot of data movement or just use a circle here! */
  13293. for (i = 0, j = pv->D; j < pv->N; i++, j++)
  13294. pv->in_data[i] = pv->in_data[j];
  13295. if (pv->block_input)
  13296. pv->block_input(pv->closure, 1, pv->in_data, pv->N - pv->D, pv->N);
  13297. else
  13298. {
  13299. for (i = pv->N - pv->D; i < pv->N; i++)
  13300. pv->in_data[i] = pv->input(pv->closure, 1);
  13301. }
  13302. }
  13303. buf = pv->filptr % pv->N;
  13304. for (i = 0; i < pv->N; i++)
  13305. {
  13306. pv->ampinc[buf++] = pv->win[i] * pv->in_data[i];
  13307. if (buf >= pv->N) buf = 0;
  13308. }
  13309. pv->filptr += pv->D;
  13310. mus_fft(pv->ampinc, pv->freqs, pv->N, 1);
  13311. mus_rectangular_to_polar(pv->ampinc, pv->freqs, N2);
  13312. }
  13313. if ((pv_edit == NULL) ||
  13314. ((*pv_edit)(pv->closure)))
  13315. {
  13316. mus_float_t pscl, kscl, ks;
  13317. pscl = 1.0 / (mus_float_t)(pv->D);
  13318. kscl = TWO_PI / (mus_float_t)(pv->N);
  13319. for (i = 0, ks = 0.0; i < N2; i++, ks += kscl)
  13320. {
  13321. mus_float_t diff;
  13322. diff = pv->freqs[i] - pv->lastphase[i];
  13323. pv->lastphase[i] = pv->freqs[i];
  13324. while (diff > M_PI) diff -= TWO_PI;
  13325. while (diff < -M_PI) diff += TWO_PI;
  13326. pv->freqs[i] = pv->pitch * (diff * pscl + ks);
  13327. }
  13328. }
  13329. /* it's possible to build the endpoint waveforms here and interpolate, but there is no savings.
  13330. * other pvocs use ifft rather than sin-bank, but then they have to make excuses.
  13331. * Something I didn't expect -- the algorithm above focusses on the active frequency!
  13332. * For example, the 4 or so bins around a given peak all tighten
  13333. * to 4 bins running at almost exactly the same frequency (the center).
  13334. */
  13335. scl = 1.0 / (mus_float_t)(pv->interp);
  13336. #if HAVE_SINCOS
  13337. pv->topN = 0;
  13338. #else
  13339. pv->topN = N2;
  13340. #endif
  13341. for (i = 0; i < N2; i++)
  13342. {
  13343. #if HAVE_SINCOS
  13344. double s, c;
  13345. bool amp_zero;
  13346. amp_zero = ((pv->amps[i] < 1e-7) && (pv->ampinc[i] == 0.0));
  13347. if (!amp_zero)
  13348. {
  13349. pv->indices[pv->topN++] = i;
  13350. pv->sc_safe[i] = (fabs(pv->freqs[i] - pv->phaseinc[i]) < 0.02); /* .5 is too big, .01 and .03 ok by tests */
  13351. if (pv->sc_safe[i])
  13352. {
  13353. sincos((pv->freqs[i] + pv->phaseinc[i]) * 0.5, &s, &c);
  13354. pv->sn[i] = s;
  13355. pv->cs[i] = c;
  13356. }
  13357. }
  13358. if ((!(pv->synthesize)) && (amp_zero))
  13359. {
  13360. pv->phases[i] += (pv->interp * (pv->freqs[i] + pv->phaseinc[i]) * 0.5);
  13361. pv->phaseinc[i] = pv->freqs[i];
  13362. }
  13363. else
  13364. {
  13365. pv->ampinc[i] = scl * (pv->ampinc[i] - pv->amps[i]);
  13366. pv->freqs[i] = scl * (pv->freqs[i] - pv->phaseinc[i]);
  13367. }
  13368. #else
  13369. pv->ampinc[i] = scl * (pv->ampinc[i] - pv->amps[i]);
  13370. pv->freqs[i] = scl * (pv->freqs[i] - pv->phaseinc[i]);
  13371. #endif
  13372. }
  13373. }
  13374. pv->outctr++;
  13375. if (pv_synthesize)
  13376. return((*pv_synthesize)(pv->closure));
  13377. if (pv->calc)
  13378. {
  13379. mus_float_t *pinc, *frq, *ph, *amp, *panc;
  13380. int topN;
  13381. #if HAVE_SINCOS
  13382. int j;
  13383. double *cs, *sn;
  13384. #endif
  13385. topN = pv->topN;
  13386. pinc = pv->phaseinc;
  13387. frq = pv->freqs;
  13388. ph = pv->phases;
  13389. amp = pv->amps;
  13390. panc = pv->ampinc;
  13391. #if HAVE_SINCOS
  13392. cs = pv->cs;
  13393. sn = pv->sn;
  13394. #endif
  13395. sum = 0.0;
  13396. sum1 = 0.0;
  13397. /* amps can be negative here due to rounding troubles
  13398. * sincos is faster (using shell time command) except in virtualbox running linux on a mac?
  13399. * (callgrind does not handle sincos correctly).
  13400. *
  13401. * this version (22-Jan-14) is slower if no sincos;
  13402. * if sincos, we use sin(a + b) = sin(a)cos(b) + cos(a)sin(b)
  13403. * since sin(b) and cos(b) are constant through the pv->interp (implicit) loop, they are calculated once above.
  13404. * Then here we calculate 2 samples on each run through this loop. I wonder if we could center the true case,
  13405. * and get 3 samples? If 2, the difference is very small (we're taking the midpoint of the phase increment change,
  13406. * so the two are not quite the same). In tests, 10000 samples, channel-distance is ca .15.
  13407. *
  13408. * If the amp zero phase is off (incorrectly incremented above), the effect is a sort of low-pass filter??
  13409. * Are we getting cancellation from the overlap?
  13410. */
  13411. #if HAVE_SINCOS
  13412. for (j = 0; j < topN; j++)
  13413. {
  13414. double sx, cx;
  13415. i = pv->indices[j];
  13416. pinc[i] += frq[i];
  13417. ph[i] += pinc[i];
  13418. amp[i] += panc[i];
  13419. sincos(ph[i], &sx, &cx);
  13420. sum += (amp[i] * sx);
  13421. pinc[i] += frq[i];
  13422. ph[i] += pinc[i];
  13423. amp[i] += panc[i];
  13424. if (pv->sc_safe[i])
  13425. sum1 += amp[i] * (sx * cs[i] + cx * sn[i]);
  13426. else sum1 += amp[i] * sin(ph[i]);
  13427. }
  13428. #else
  13429. for (i = 0; i < topN; i++)
  13430. {
  13431. pinc[i] += frq[i];
  13432. ph[i] += pinc[i];
  13433. amp[i] += panc[i];
  13434. if (amp[i] > 0.0) sum += amp[i] * sin(ph[i]);
  13435. pinc[i] += frq[i];
  13436. ph[i] += pinc[i];
  13437. amp[i] += panc[i];
  13438. if (amp[i] > 0.0) sum1 += amp[i] * sin(ph[i]);
  13439. }
  13440. #endif
  13441. pv->sum1 = sum1;
  13442. pv->calc = false;
  13443. return(sum);
  13444. }
  13445. pv->calc = true;
  13446. return(pv->sum1);
  13447. }
  13448. mus_float_t mus_phase_vocoder(mus_any *ptr, mus_float_t (*input)(void *arg, int direction))
  13449. {
  13450. return(mus_phase_vocoder_with_editors(ptr, input, NULL, NULL, NULL));
  13451. }
  13452. void mus_generator_set_feeders(mus_any *g,
  13453. mus_float_t (*feed)(void *arg, int direction),
  13454. mus_float_t (*block_feed)(void *arg, int direction, mus_float_t *block, mus_long_t start, mus_long_t end))
  13455. {
  13456. if (mus_is_src(g))
  13457. {
  13458. ((sr *)g)->feeder = feed;
  13459. ((sr *)g)->block_feeder = block_feed;
  13460. }
  13461. else
  13462. {
  13463. if (mus_is_granulate(g))
  13464. {
  13465. ((grn_info *)g)->rd = feed;
  13466. ((grn_info *)g)->block_rd = block_feed;
  13467. }
  13468. else
  13469. {
  13470. if (mus_is_phase_vocoder(g))
  13471. {
  13472. ((pv_info *)g)->input = feed;
  13473. ((pv_info *)g)->block_input = block_feed;
  13474. }
  13475. else
  13476. {
  13477. if (mus_is_convolve(g))
  13478. {
  13479. ((conv *)g)->feeder = feed;
  13480. ((conv *)g)->block_feeder = block_feed;
  13481. }
  13482. }
  13483. }
  13484. }
  13485. }
  13486. void mus_generator_copy_feeders(mus_any *dest, mus_any *source)
  13487. {
  13488. if (mus_is_src(dest))
  13489. {
  13490. ((sr *)dest)->feeder = ((sr *)source)->feeder;
  13491. ((sr *)dest)->block_feeder = ((sr *)source)->block_feeder;
  13492. }
  13493. else
  13494. {
  13495. if (mus_is_granulate(dest))
  13496. {
  13497. ((grn_info *)dest)->rd = ((grn_info *)source)->rd;
  13498. ((grn_info *)dest)->block_rd = ((grn_info *)source)->block_rd;
  13499. }
  13500. else
  13501. {
  13502. if (mus_is_phase_vocoder(dest))
  13503. {
  13504. ((pv_info *)dest)->input = ((pv_info *)source)->input;
  13505. ((pv_info *)dest)->block_input = ((pv_info *)source)->block_input;
  13506. }
  13507. else
  13508. {
  13509. if (mus_is_convolve(dest))
  13510. {
  13511. ((conv *)dest)->feeder = ((conv *)source)->feeder;
  13512. ((conv *)dest)->block_feeder = ((conv *)source)->block_feeder;
  13513. }
  13514. }
  13515. }
  13516. }
  13517. }
  13518. /* ---------------- single sideband "suppressed carrier" amplitude modulation (ssb-am) ---------------- */
  13519. typedef struct {
  13520. mus_any_class *core;
  13521. bool shift_up;
  13522. mus_float_t *coeffs;
  13523. mus_any *hilbert, *dly;
  13524. #if (!HAVE_SINCOS)
  13525. mus_any *sin_osc, *cos_osc;
  13526. #else
  13527. double phase, freq, sign;
  13528. #endif
  13529. int size;
  13530. } ssbam;
  13531. bool mus_is_ssb_am(mus_any *ptr)
  13532. {
  13533. return((ptr) &&
  13534. (ptr->core->type == MUS_SSB_AM));
  13535. }
  13536. static mus_float_t run_hilbert(flt *gen, mus_float_t input)
  13537. {
  13538. mus_float_t xout = 0.0;
  13539. mus_float_t *state, *ts, *x, *end;
  13540. x = (mus_float_t *)(gen->x);
  13541. state = (mus_float_t *)(gen->state + gen->loc);
  13542. ts = (mus_float_t *)(state + gen->order);
  13543. (*state) = input;
  13544. (*ts) = input;
  13545. state += 2;
  13546. end = (mus_float_t *)(state + 20);
  13547. while (ts > end)
  13548. {
  13549. xout += (*ts) * (*x); ts -= 2; x += 2;
  13550. xout += (*ts) * (*x); ts -= 2; x += 2;
  13551. xout += (*ts) * (*x); ts -= 2; x += 2;
  13552. xout += (*ts) * (*x); ts -= 2; x += 2;
  13553. xout += (*ts) * (*x); ts -= 2; x += 2;
  13554. xout += (*ts) * (*x); ts -= 2; x += 2;
  13555. xout += (*ts) * (*x); ts -= 2; x += 2;
  13556. xout += (*ts) * (*x); ts -= 2; x += 2;
  13557. xout += (*ts) * (*x); ts -= 2; x += 2;
  13558. xout += (*ts) * (*x); ts -= 2; x += 2;
  13559. }
  13560. while (ts > state)
  13561. {
  13562. xout += (*ts) * (*x); ts -= 2; x += 2;
  13563. }
  13564. gen->loc++;
  13565. if (gen->loc == gen->order)
  13566. gen->loc = 0;
  13567. return(xout + ((*ts) * (*x)));
  13568. #if 0
  13569. int i, len;
  13570. mus_float_t val = 0.0;
  13571. len = g->order;
  13572. g->state[0] = insig;
  13573. for (i = 0; i < len; i += 2) val += (g->x[i] * g->state[i]);
  13574. for (i = len - 1; i >= 1; i--) g->state[i] = g->state[i - 1];
  13575. return(val);
  13576. #endif
  13577. }
  13578. mus_float_t mus_ssb_am_unmodulated(mus_any *ptr, mus_float_t insig)
  13579. {
  13580. ssbam *gen = (ssbam *)ptr;
  13581. #if (!HAVE_SINCOS)
  13582. return((mus_oscil_unmodulated(gen->cos_osc) * mus_delay_unmodulated_noz(gen->dly, insig)) +
  13583. (mus_oscil_unmodulated(gen->sin_osc) * run_hilbert((flt *)(gen->hilbert), insig)));
  13584. #else
  13585. double cx, sx;
  13586. sincos(gen->phase, &sx, &cx);
  13587. gen->phase += gen->freq;
  13588. return((cx * mus_delay_unmodulated_noz(gen->dly, insig)) +
  13589. (sx * gen->sign * run_hilbert((flt *)(gen->hilbert), insig)));
  13590. #endif
  13591. }
  13592. mus_float_t mus_ssb_am(mus_any *ptr, mus_float_t insig, mus_float_t fm)
  13593. {
  13594. ssbam *gen = (ssbam *)ptr;
  13595. #if (!HAVE_SINCOS)
  13596. return((mus_oscil_fm(gen->cos_osc, fm) * mus_delay_unmodulated_noz(gen->dly, insig)) +
  13597. (mus_oscil_fm(gen->sin_osc, fm) * run_hilbert((flt *)(gen->hilbert), insig)));
  13598. #else
  13599. double cx, sx;
  13600. sincos(gen->phase, &sx, &cx);
  13601. gen->phase += (fm + gen->freq);
  13602. return((cx * mus_delay_unmodulated_noz(gen->dly, insig)) +
  13603. (sx * gen->sign * run_hilbert((flt *)(gen->hilbert), insig)));
  13604. #endif
  13605. }
  13606. static void free_ssb_am(mus_any *ptr)
  13607. {
  13608. ssbam *gen = (ssbam *)ptr;
  13609. mus_free(gen->dly);
  13610. mus_free(gen->hilbert);
  13611. #if (!HAVE_SINCOS)
  13612. mus_free(gen->cos_osc);
  13613. mus_free(gen->sin_osc);
  13614. #endif
  13615. if (gen->coeffs) {free(gen->coeffs); gen->coeffs = NULL;}
  13616. free(ptr);
  13617. }
  13618. static mus_any *ssbam_copy(mus_any *ptr)
  13619. {
  13620. ssbam *g, *p;
  13621. int bytes;
  13622. p = (ssbam *)ptr;
  13623. g = (ssbam *)malloc(sizeof(ssbam));
  13624. memcpy((void *)g, (void *)ptr, sizeof(ssbam));
  13625. g->dly = mus_copy(p->dly);
  13626. g->hilbert = mus_copy(p->hilbert);
  13627. #if (!HAVE_SINCOS)
  13628. g->cos_osc = mus_copy(p->cos_osc);
  13629. g->sin_osc = mus_copy(p->sin_osc);
  13630. #endif
  13631. bytes = p->size * sizeof(mus_float_t);
  13632. g->coeffs = (mus_float_t *)malloc(bytes);
  13633. memcpy((void *)(g->coeffs), (void *)(p->coeffs), bytes);
  13634. return((mus_any *)g);
  13635. }
  13636. static mus_float_t ssb_am_freq(mus_any *ptr)
  13637. {
  13638. #if (!HAVE_SINCOS)
  13639. return(mus_radians_to_hz(((osc *)((ssbam *)ptr)->sin_osc)->freq));
  13640. #else
  13641. return(mus_radians_to_hz(((ssbam *)ptr)->freq));
  13642. #endif
  13643. }
  13644. static mus_float_t ssb_am_set_freq(mus_any *ptr, mus_float_t val)
  13645. {
  13646. ssbam *gen = (ssbam *)ptr;
  13647. mus_float_t rads;
  13648. rads = mus_hz_to_radians(val);
  13649. #if (!HAVE_SINCOS)
  13650. ((osc *)(gen->sin_osc))->freq = rads;
  13651. ((osc *)(gen->cos_osc))->freq = rads;
  13652. #else
  13653. gen->freq = rads;
  13654. #endif
  13655. return(val);
  13656. }
  13657. static mus_float_t ssb_am_increment(mus_any *ptr)
  13658. {
  13659. #if (!HAVE_SINCOS)
  13660. return(((osc *)((ssbam *)ptr)->sin_osc)->freq);
  13661. #else
  13662. return(((ssbam *)ptr)->freq);
  13663. #endif
  13664. }
  13665. static mus_float_t ssb_am_set_increment(mus_any *ptr, mus_float_t val)
  13666. {
  13667. ssbam *gen = (ssbam *)ptr;
  13668. #if (!HAVE_SINCOS)
  13669. ((osc *)(gen->sin_osc))->freq = val;
  13670. ((osc *)(gen->cos_osc))->freq = val;
  13671. #else
  13672. gen->freq = val;
  13673. #endif
  13674. return(val);
  13675. }
  13676. static mus_float_t ssb_am_phase(mus_any *ptr)
  13677. {
  13678. #if (!HAVE_SINCOS)
  13679. return(fmod(((osc *)((ssbam *)ptr)->cos_osc)->phase - 0.5 * M_PI, TWO_PI));
  13680. #else
  13681. return(fmod(((ssbam *)ptr)->phase, TWO_PI));
  13682. #endif
  13683. }
  13684. static mus_float_t ssb_am_set_phase(mus_any *ptr, mus_float_t val)
  13685. {
  13686. ssbam *gen = (ssbam *)ptr;
  13687. #if (!HAVE_SINCOS)
  13688. if (gen->shift_up)
  13689. ((osc *)(gen->sin_osc))->phase = val + M_PI;
  13690. else ((osc *)(gen->sin_osc))->phase = val;
  13691. ((osc *)(gen->cos_osc))->phase = val + 0.5 * M_PI;
  13692. #else
  13693. gen->phase = val;
  13694. #endif
  13695. return(val);
  13696. }
  13697. static mus_long_t ssb_am_order(mus_any *ptr) {return(mus_order(((ssbam *)ptr)->dly));}
  13698. static int ssb_am_interp_type(mus_any *ptr) {return(delay_interp_type(((ssbam *)ptr)->dly));}
  13699. static mus_float_t *ssb_am_data(mus_any *ptr) {return(filter_data(((ssbam *)ptr)->hilbert));}
  13700. static mus_float_t ssb_am_run(mus_any *ptr, mus_float_t insig, mus_float_t fm) {return(mus_ssb_am(ptr, insig, fm));}
  13701. static mus_float_t *ssb_am_xcoeffs(mus_any *ptr) {return(mus_xcoeffs(((ssbam *)ptr)->hilbert));}
  13702. static mus_float_t ssb_am_xcoeff(mus_any *ptr, int index) {return(mus_xcoeff(((ssbam *)ptr)->hilbert, index));}
  13703. static mus_float_t ssb_am_set_xcoeff(mus_any *ptr, int index, mus_float_t val) {return(mus_set_xcoeff(((ssbam *)ptr)->hilbert, index, val));}
  13704. static bool ssb_am_equalp(mus_any *p1, mus_any *p2)
  13705. {
  13706. return((p1 == p2) ||
  13707. ((mus_is_ssb_am((mus_any *)p1)) &&
  13708. (mus_is_ssb_am((mus_any *)p2)) &&
  13709. (((ssbam *)p1)->shift_up == ((ssbam *)p2)->shift_up) &&
  13710. #if (!HAVE_SINCOS)
  13711. (mus_equalp(((ssbam *)p1)->sin_osc, ((ssbam *)p2)->sin_osc)) &&
  13712. (mus_equalp(((ssbam *)p1)->cos_osc, ((ssbam *)p2)->cos_osc)) &&
  13713. #else
  13714. (((ssbam *)p1)->freq == ((ssbam *)p2)->freq) &&
  13715. (((ssbam *)p1)->phase == ((ssbam *)p2)->phase) &&
  13716. #endif
  13717. (mus_equalp(((ssbam *)p1)->dly, ((ssbam *)p2)->dly)) &&
  13718. (mus_equalp(((ssbam *)p1)->hilbert, ((ssbam *)p2)->hilbert))));
  13719. }
  13720. static char *describe_ssb_am(mus_any *ptr)
  13721. {
  13722. ssbam *gen = (ssbam *)ptr;
  13723. char *describe_buffer;
  13724. describe_buffer = (char *)malloc(DESCRIBE_BUFFER_SIZE);
  13725. snprintf(describe_buffer, DESCRIBE_BUFFER_SIZE, "%s shift: %s, sin/cos: %f Hz (%f radians), order: %d",
  13726. mus_name(ptr),
  13727. (gen->shift_up) ? "up" : "down",
  13728. mus_frequency(ptr),
  13729. mus_phase(ptr),
  13730. (int)mus_order(ptr));
  13731. return(describe_buffer);
  13732. }
  13733. static void ssb_reset(mus_any *ptr)
  13734. {
  13735. ssbam *gen = (ssbam *)ptr;
  13736. ssb_am_set_phase(ptr, 0.0);
  13737. mus_reset(gen->dly);
  13738. mus_reset(gen->hilbert);
  13739. }
  13740. static mus_any_class SSB_AM_CLASS = {
  13741. MUS_SSB_AM,
  13742. (char *)S_ssb_am,
  13743. &free_ssb_am,
  13744. &describe_ssb_am,
  13745. &ssb_am_equalp,
  13746. &ssb_am_data, 0,
  13747. &ssb_am_order, 0,
  13748. &ssb_am_freq,
  13749. &ssb_am_set_freq,
  13750. &ssb_am_phase,
  13751. &ssb_am_set_phase,
  13752. &fallback_scaler, 0,
  13753. &ssb_am_increment,
  13754. &ssb_am_set_increment,
  13755. &ssb_am_run,
  13756. MUS_NOT_SPECIAL,
  13757. NULL,
  13758. &ssb_am_interp_type,
  13759. 0, 0, 0, 0,
  13760. &ssb_am_xcoeff, &ssb_am_set_xcoeff,
  13761. 0, 0, 0, 0,
  13762. 0, 0, 0, 0, 0, 0, 0,
  13763. 0, 0,
  13764. &ssb_am_xcoeffs, 0,
  13765. &ssb_reset,
  13766. 0, &ssbam_copy
  13767. };
  13768. static int ssb_am_last_flen = -1;
  13769. static mus_float_t *ssb_am_last_coeffs = NULL;
  13770. mus_any *mus_make_ssb_am(mus_float_t freq, int order)
  13771. {
  13772. ssbam *gen;
  13773. int len, flen;
  13774. if ((order & 1) == 0) order++; /* if order is even, the first Hilbert coeff is 0.0 */
  13775. gen = (ssbam *)malloc(sizeof(ssbam));
  13776. gen->core = &SSB_AM_CLASS;
  13777. if (freq > 0)
  13778. gen->shift_up = true;
  13779. else gen->shift_up = false;
  13780. #if (!HAVE_SINCOS)
  13781. gen->sin_osc = mus_make_oscil(fabs(freq), (gen->shift_up) ? M_PI : 0.0);
  13782. gen->cos_osc = mus_make_oscil(fabs(freq), M_PI * 0.5);
  13783. #else
  13784. if (gen->shift_up) gen->sign = -1.0; else gen->sign = 1.0;
  13785. gen->freq = mus_hz_to_radians(fabs(freq));
  13786. gen->phase = 0.0;
  13787. #endif
  13788. gen->dly = mus_make_delay(order, NULL, order, MUS_INTERP_NONE);
  13789. len = order * 2 + 1;
  13790. flen = len + 1; /* even -- need 4 */
  13791. if ((flen & 2) != 0) flen += 2;
  13792. gen->size = flen;
  13793. if ((flen == ssb_am_last_flen) && (ssb_am_last_coeffs))
  13794. {
  13795. gen->coeffs = (mus_float_t *)malloc(flen * sizeof(mus_float_t));
  13796. memcpy((void *)(gen->coeffs), (const void *)ssb_am_last_coeffs, flen * sizeof(mus_float_t));
  13797. }
  13798. else
  13799. {
  13800. int i, k;
  13801. gen->coeffs = (mus_float_t *)calloc(flen, sizeof(mus_float_t));
  13802. for (i = -order, k = 0; i <= order; i++, k++)
  13803. {
  13804. mus_float_t denom, num;
  13805. denom = i * M_PI;
  13806. num = 1.0 - cos(denom);
  13807. if (i == 0)
  13808. gen->coeffs[k] = 0.0;
  13809. else gen->coeffs[k] = (num / denom) * (0.54 + (0.46 * cos(denom / order)));
  13810. }
  13811. /* so odd numbered coeffs are zero */
  13812. /* can't be too fancy here because there might be several of these gens running in parallel at different sizes */
  13813. if (ssb_am_last_coeffs) free(ssb_am_last_coeffs);
  13814. ssb_am_last_flen = flen;
  13815. ssb_am_last_coeffs = (mus_float_t *)malloc(flen * sizeof(mus_float_t));
  13816. memcpy((void *)(ssb_am_last_coeffs), (const void *)(gen->coeffs), flen * sizeof(mus_float_t));
  13817. }
  13818. gen->hilbert = mus_make_fir_filter(flen, gen->coeffs, NULL);
  13819. return((mus_any *)gen);
  13820. }
  13821. /* (define (hi) (let ((g (make-ssb-am 100.0))) (ssb-am g 1.0) (ssb-am g 0.0))) */
  13822. /* ---------------- mus-apply ---------------- */
  13823. mus_float_t (*mus_run_function(mus_any *g))(mus_any *gen, mus_float_t arg1, mus_float_t arg2)
  13824. {
  13825. if (g)
  13826. return(g->core->run);
  13827. return(NULL);
  13828. }
  13829. mus_float_t mus_apply(mus_any *gen, mus_float_t f1, mus_float_t f2)
  13830. {
  13831. /* what about non-gen funcs such as polynomial, ring_modulate etc? */
  13832. if ((gen) && (gen->core->run))
  13833. return((*(gen->core->run))(gen, f1, f2));
  13834. return(0.0);
  13835. }
  13836. /* ---------------- mix files ---------------- */
  13837. /* a mixing "instrument" along the lines of the mix function in clm */
  13838. /* this is a very commonly used function, so it's worth picking out the special cases for optimization */
  13839. #define IDENTITY_MIX 0
  13840. #define IDENTITY_MONO_MIX 1
  13841. #define SCALED_MONO_MIX 2
  13842. #define SCALED_MIX 3
  13843. #define ENVELOPED_MONO_MIX 4
  13844. #define ENVELOPED_MIX 5
  13845. #define ALL_MIX 6
  13846. static int mix_file_type(int out_chans, int in_chans, mus_float_t *mx, mus_any ***envs)
  13847. {
  13848. if (envs)
  13849. {
  13850. if ((in_chans == 1) && (out_chans == 1))
  13851. {
  13852. if (envs[0][0])
  13853. return(ENVELOPED_MONO_MIX);
  13854. return(SCALED_MONO_MIX);
  13855. }
  13856. else
  13857. {
  13858. if (mx)
  13859. return(ALL_MIX);
  13860. return(ENVELOPED_MIX);
  13861. }
  13862. }
  13863. if (mx)
  13864. {
  13865. int i, j;
  13866. if ((in_chans == 1) && (out_chans == 1))
  13867. {
  13868. if (mx[0] == 1.0)
  13869. return(IDENTITY_MONO_MIX);
  13870. return(SCALED_MONO_MIX);
  13871. }
  13872. for (i = 0; i < out_chans; i++)
  13873. for (j = 0; j < in_chans; j++)
  13874. if (((i == j) && (mx[i * in_chans + j] != 1.0)) ||
  13875. ((i != j) && (mx[i * in_chans + j] != 0.0)))
  13876. return(SCALED_MIX);
  13877. }
  13878. if ((in_chans == 1) && (out_chans == 1))
  13879. return(IDENTITY_MONO_MIX);
  13880. return(IDENTITY_MIX);
  13881. }
  13882. void mus_file_mix_with_reader_and_writer(mus_any *outf, mus_any *inf,
  13883. mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start,
  13884. mus_float_t *mx, int mx_chans,
  13885. mus_any ***envs)
  13886. {
  13887. int mixtype, in_chans, out_chans;
  13888. mus_long_t inc, outc, out_end;
  13889. mus_float_t *out_data, *in_data, *local_mx;
  13890. out_chans = mus_channels(outf);
  13891. if (out_chans <= 0)
  13892. mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", mus_describe(outf), out_chans);
  13893. in_chans = mus_channels(inf);
  13894. if (in_chans <= 0)
  13895. mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", mus_describe(inf), in_chans);
  13896. out_end = out_start + out_framples;
  13897. mixtype = mix_file_type(out_chans, in_chans, mx, envs);
  13898. in_data = (mus_float_t *)calloc((in_chans < out_chans) ? out_chans : in_chans, sizeof(mus_float_t));
  13899. out_data = (mus_float_t *)calloc((in_chans < out_chans) ? out_chans : in_chans, sizeof(mus_float_t));
  13900. local_mx = mx;
  13901. switch (mixtype)
  13902. {
  13903. case ENVELOPED_MONO_MIX:
  13904. {
  13905. mus_any *e;
  13906. e = envs[0][0];
  13907. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13908. {
  13909. mus_file_to_frample(inf, inc, in_data);
  13910. mus_outa_to_file(outf, outc, in_data[0] * mus_env(e));
  13911. }
  13912. }
  13913. break;
  13914. case ENVELOPED_MIX:
  13915. if (mx == NULL)
  13916. {
  13917. int i;
  13918. mx_chans = (in_chans < out_chans) ? out_chans : in_chans;
  13919. local_mx = (mus_float_t *)calloc(mx_chans * mx_chans, sizeof(mus_float_t));
  13920. for (i = 0; i < mx_chans; i++)
  13921. local_mx[i * mx_chans + i] = 1.0;
  13922. }
  13923. /* fall through */
  13924. case ALL_MIX:
  13925. /* the general case -- possible envs/scalers on every mixer cell */
  13926. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13927. {
  13928. int j, k;
  13929. for (j = 0; j < in_chans; j++)
  13930. for (k = 0; k < out_chans; k++)
  13931. if (envs[j][k])
  13932. local_mx[j * mx_chans + k] = mus_env(envs[j][k]);
  13933. mus_frample_to_file(outf, outc, mus_frample_to_frample(local_mx, mx_chans, mus_file_to_frample(inf, inc, in_data), in_chans, out_data, out_chans));
  13934. }
  13935. if (mx == NULL) free(local_mx);
  13936. break;
  13937. case IDENTITY_MONO_MIX:
  13938. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13939. {
  13940. mus_file_to_frample(inf, inc, in_data);
  13941. mus_outa_to_file(outf, outc, in_data[0]);
  13942. }
  13943. break;
  13944. case IDENTITY_MIX:
  13945. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13946. mus_frample_to_file(outf, outc, mus_file_to_frample(inf, inc, in_data));
  13947. break;
  13948. case SCALED_MONO_MIX:
  13949. {
  13950. mus_float_t scl;
  13951. scl = mx[0];
  13952. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13953. {
  13954. mus_file_to_frample(inf, inc, in_data);
  13955. mus_outa_to_file(outf, outc, scl * in_data[0]);
  13956. }
  13957. }
  13958. break;
  13959. case SCALED_MIX:
  13960. for (inc = in_start, outc = out_start; outc < out_end; inc++, outc++)
  13961. mus_frample_to_file(outf, outc, mus_frample_to_frample(mx, mx_chans, mus_file_to_frample(inf, inc, in_data), in_chans, out_data, out_chans));
  13962. break;
  13963. }
  13964. free(in_data);
  13965. free(out_data);
  13966. }
  13967. void mus_file_mix(const char *outfile, const char *infile,
  13968. mus_long_t out_start, mus_long_t out_framples, mus_long_t in_start,
  13969. mus_float_t *mx, int mx_chans,
  13970. mus_any ***envs)
  13971. {
  13972. int in_chans, out_chans, min_chans, mixtype;
  13973. out_chans = mus_sound_chans(outfile);
  13974. if (out_chans <= 0)
  13975. mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", outfile, out_chans);
  13976. in_chans = mus_sound_chans(infile);
  13977. if (in_chans <= 0)
  13978. mus_error(MUS_NO_CHANNELS, S_mus_file_mix ": %s chans: %d", infile, in_chans);
  13979. if (out_chans > in_chans)
  13980. min_chans = in_chans;
  13981. else min_chans = out_chans;
  13982. mixtype = mix_file_type(out_chans, in_chans, mx, envs);
  13983. if (mixtype == ALL_MIX)
  13984. {
  13985. mus_any *inf, *outf;
  13986. /* the general case -- possible envs/scalers on every mixer cell */
  13987. outf = mus_continue_sample_to_file(outfile);
  13988. inf = mus_make_file_to_frample(infile);
  13989. mus_file_mix_with_reader_and_writer(outf, inf, out_start, out_framples, in_start, mx, mx_chans, envs);
  13990. mus_free(inf);
  13991. mus_free(outf);
  13992. }
  13993. else
  13994. {
  13995. mus_long_t j = 0;
  13996. int i, m, ofd, ifd;
  13997. mus_float_t scaler;
  13998. mus_any *e;
  13999. mus_float_t **obufs, **ibufs;
  14000. mus_long_t offk, curoutframples;
  14001. /* highly optimizable cases */
  14002. obufs = (mus_float_t **)malloc(out_chans * sizeof(mus_float_t *));
  14003. for (i = 0; i < out_chans; i++)
  14004. obufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t));
  14005. ibufs = (mus_float_t **)malloc(in_chans * sizeof(mus_float_t *));
  14006. for (i = 0; i < in_chans; i++)
  14007. ibufs[i] = (mus_float_t *)malloc(clm_file_buffer_size * sizeof(mus_float_t));
  14008. ifd = mus_sound_open_input(infile);
  14009. mus_file_seek_frample(ifd, in_start);
  14010. mus_file_read(ifd, in_start, clm_file_buffer_size, in_chans, ibufs);
  14011. ofd = mus_sound_reopen_output(outfile,
  14012. out_chans,
  14013. mus_sound_sample_type(outfile),
  14014. mus_sound_header_type(outfile),
  14015. mus_sound_data_location(outfile));
  14016. curoutframples = mus_sound_framples(outfile);
  14017. mus_file_seek_frample(ofd, out_start);
  14018. mus_file_read(ofd, out_start, clm_file_buffer_size, out_chans, obufs);
  14019. mus_file_seek_frample(ofd, out_start);
  14020. switch (mixtype)
  14021. {
  14022. case IDENTITY_MONO_MIX:
  14023. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14024. {
  14025. if (j == clm_file_buffer_size)
  14026. {
  14027. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14028. j = 0;
  14029. mus_file_seek_frample(ofd, out_start + offk);
  14030. mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs);
  14031. mus_file_seek_frample(ofd, out_start + offk);
  14032. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14033. }
  14034. obufs[0][j] += ibufs[0][j];
  14035. }
  14036. break;
  14037. case IDENTITY_MIX:
  14038. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14039. {
  14040. if (j == clm_file_buffer_size)
  14041. {
  14042. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14043. j = 0;
  14044. mus_file_seek_frample(ofd, out_start + offk);
  14045. mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs);
  14046. mus_file_seek_frample(ofd, out_start + offk);
  14047. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14048. }
  14049. for (i = 0; i < min_chans; i++)
  14050. obufs[i][j] += ibufs[i][j];
  14051. }
  14052. break;
  14053. case SCALED_MONO_MIX:
  14054. scaler = mx[0];
  14055. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14056. {
  14057. if (j == clm_file_buffer_size)
  14058. {
  14059. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14060. j = 0;
  14061. mus_file_seek_frample(ofd, out_start + offk);
  14062. mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs);
  14063. mus_file_seek_frample(ofd, out_start + offk);
  14064. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14065. }
  14066. obufs[0][j] += (mus_float_t)(scaler * ibufs[0][j]);
  14067. }
  14068. break;
  14069. case SCALED_MIX:
  14070. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14071. {
  14072. if (j == clm_file_buffer_size)
  14073. {
  14074. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14075. j = 0;
  14076. mus_file_seek_frample(ofd, out_start + offk);
  14077. mus_file_read(ofd, out_start + offk, clm_file_buffer_size , out_chans, obufs);
  14078. mus_file_seek_frample(ofd, out_start + offk);
  14079. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14080. }
  14081. for (i = 0; i < min_chans; i++)
  14082. for (m = 0; m < in_chans; m++)
  14083. obufs[i][j] += (mus_float_t)(ibufs[m][j] * mx[m * mx_chans + i]);
  14084. }
  14085. break;
  14086. case ENVELOPED_MONO_MIX:
  14087. e = envs[0][0];
  14088. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14089. {
  14090. if (j == clm_file_buffer_size)
  14091. {
  14092. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14093. j = 0;
  14094. mus_file_seek_frample(ofd, out_start + offk);
  14095. mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs);
  14096. mus_file_seek_frample(ofd, out_start + offk);
  14097. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14098. }
  14099. obufs[0][j] += (mus_float_t)(mus_env(e) * ibufs[0][j]);
  14100. }
  14101. break;
  14102. case ENVELOPED_MIX:
  14103. e = envs[0][0];
  14104. for (offk = 0, j = 0; offk < out_framples; offk++, j++)
  14105. {
  14106. if (j == clm_file_buffer_size)
  14107. {
  14108. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14109. j = 0;
  14110. mus_file_seek_frample(ofd, out_start + offk);
  14111. mus_file_read(ofd, out_start + offk, clm_file_buffer_size, out_chans, obufs);
  14112. mus_file_seek_frample(ofd, out_start + offk);
  14113. mus_file_read(ifd, in_start + offk, clm_file_buffer_size, in_chans, ibufs);
  14114. }
  14115. scaler = mus_env(e);
  14116. for (i = 0; i < min_chans; i++)
  14117. obufs[i][j] += (mus_float_t)(scaler * ibufs[i][j]);
  14118. }
  14119. break;
  14120. }
  14121. if (j > 0)
  14122. mus_file_write(ofd, 0, j - 1, out_chans, obufs);
  14123. if (curoutframples < (out_framples + out_start))
  14124. curoutframples = out_framples + out_start;
  14125. mus_sound_close_output(ofd, curoutframples * out_chans * mus_bytes_per_sample(mus_sound_sample_type(outfile)));
  14126. mus_sound_close_input(ifd);
  14127. for (i = 0; i < in_chans; i++) free(ibufs[i]);
  14128. free(ibufs);
  14129. for (i = 0; i < out_chans; i++) free(obufs[i]);
  14130. free(obufs);
  14131. }
  14132. }
  14133. /* ---------------- init clm ---------------- */
  14134. void mus_initialize(void)
  14135. {
  14136. #define MULAW_ZERO 255
  14137. #define ALAW_ZERO 213
  14138. #define UBYTE_ZERO 128
  14139. mus_generator_type = MUS_INITIAL_GEN_TAG;
  14140. sampling_rate = MUS_DEFAULT_SAMPLING_RATE;
  14141. w_rate = (TWO_PI / MUS_DEFAULT_SAMPLING_RATE);
  14142. array_print_length = MUS_DEFAULT_ARRAY_PRINT_LENGTH;
  14143. clm_file_buffer_size = MUS_DEFAULT_FILE_BUFFER_SIZE;
  14144. #if HAVE_FFTW3 && HAVE_COMPLEX_TRIG
  14145. last_c_fft_size = 0;
  14146. /* is there a problem if the caller built fftw with --enable-threads?
  14147. * How to tell via configure that we need to initialize the thread stuff in libfftw?
  14148. */
  14149. #endif
  14150. sincs = 0;
  14151. locsig_warned = NULL;
  14152. sample_type_zero = (int *)calloc(MUS_NUM_SAMPLES, sizeof(int));
  14153. sample_type_zero[MUS_MULAW] = MULAW_ZERO;
  14154. sample_type_zero[MUS_ALAW] = ALAW_ZERO;
  14155. sample_type_zero[MUS_UBYTE] = UBYTE_ZERO;
  14156. #if MUS_LITTLE_ENDIAN
  14157. sample_type_zero[MUS_UBSHORT] = 0x80;
  14158. sample_type_zero[MUS_ULSHORT] = 0x8000;
  14159. #else
  14160. sample_type_zero[MUS_UBSHORT] = 0x8000;
  14161. sample_type_zero[MUS_ULSHORT] = 0x80;
  14162. #endif
  14163. }