You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2372 satır
66KB

  1. /* sndins.c -- Sndins for Snd/CLM
  2. *
  3. * Copyright (c) 2003-2014 Michael Scholz <mi-scholz@users.sourceforge.net>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. * SUCH DAMAGE.
  26. *
  27. * @(#)sndins.c 1.8 1/25/14
  28. */
  29. /*
  30. * instruments: fm-violin, jc-reverb, nrev, freeverb
  31. *
  32. * mus_any *mus_make_fcomb(mus_float_t scaler, int size,
  33. * mus_float_t a0, mus_float_t a1);
  34. * int mus_fcomb_p(mus_any *ptr);
  35. * mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored);
  36. *
  37. * mus_long_t ins_fm_violin(mus_float_t start, mus_float_t dur, [...]);
  38. * mus_long_t ins_jc_reverb(mus_float_t start, mus_float_t dur, [...]);
  39. * mus_long_t ins_nrev(mus_float_t start, mus_float_t dur, [...]);
  40. * mus_long_t ins_freeverb(mus_float_t start, mus_float_t dur, [...]);
  41. *
  42. * void Init_sndins(void);
  43. */
  44. #if HAVE_CONFIG_H
  45. #include <mus-config.h>
  46. #endif
  47. #include <string.h>
  48. #include <stddef.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <math.h>
  52. #include <stdarg.h>
  53. #include "_sndlib.h"
  54. #include "xen.h"
  55. #include "clm.h"
  56. #include "vct.h"
  57. #include "clm2xen.h"
  58. #include "sndins.h"
  59. #ifndef XEN_PROVIDED_P
  60. #if HAVE_SCHEME
  61. #define XEN_PROVIDED_P(feature) \
  62. XEN_TO_C_BOOLEAN(XEN_MEMBER(C_STRING_TO_XEN_SYMBOL(feature), \
  63. XEN_NAME_AS_C_STRING_TO_VALUE("*features*")))
  64. #elif HAVE_RUBY
  65. #define XEN_PROVIDED_P(feature) XEN_TO_C_BOOLEAN(rb_provided(feature))
  66. #elif HAVE_FORTH
  67. #define XEN_PROVIDED_P(feature) fth_provided_p(feature)
  68. #else
  69. #define XEN_PROVIDED_P(feature) false
  70. #endif
  71. #endif /* XEN_PROVIDED */
  72. #define INS_NO_MEMORY XEN_ERROR_TYPE("sndins-no-memory-error")
  73. #define INS_MISC XEN_ERROR_TYPE("sndins-misc-error")
  74. #define INS_ERROR(Error, Caller, Msg) \
  75. XEN_ERROR(Error, \
  76. XEN_LIST_2(C_TO_XEN_STRING(Caller), C_TO_XEN_STRING(Msg)))
  77. #define INS_MISC_ERROR(Caller, Msg) INS_ERROR(INS_MISC, Caller, Msg)
  78. #define INS_NO_MEMORY_ERROR(Caller) \
  79. INS_ERROR(INS_NO_MEMORY, Caller, "cannot allocate memory")
  80. #define SC_startime "startime"
  81. #define SC_duration "duration"
  82. #define SC_frequency "frequency"
  83. #define SC_amplitude "amplitude"
  84. #define SC_degree "degree"
  85. #define SC_distance "distance"
  86. #define SC_volume "volume"
  87. #define SC_delay1 "delay1"
  88. #define SC_delay2 "delay2"
  89. #define SC_delay3 "delay3"
  90. #define SC_delay4 "delay4"
  91. #define SC_doubled "doubled"
  92. #define SC_base "base"
  93. #define SC_damping "damping"
  94. #define SC_global "global"
  95. #define SC_predelay "predelay"
  96. #define SC_combtuning "combtuning"
  97. #define SC_allpasstuning "allpasstuning"
  98. #define SC_scaler "scaler"
  99. #define SC_size "size"
  100. #define SC_a0 "a0"
  101. #define SC_a1 "a1"
  102. #if HAVE_RUBY
  103. #define SC_amp_env "amp_env"
  104. #define SC_fm_index "fm_index"
  105. #define SC_reverb_amount "reverb_amount"
  106. #define SC_low_pass "low_pass"
  107. #define SC_periodic_vibrato_rate "periodic_vibrato_rate"
  108. #define SC_periodic_vibrato_amplitude "periodic_vibrato_amplitude"
  109. #define SC_random_vibrato_rate "random_vibrato_rate"
  110. #define SC_random_vibrato_amplitude "random_vibrato_amplitude"
  111. #define SC_noise_freq "noise_freq"
  112. #define SC_noise_amount "noise_amount"
  113. #define SC_ind_noise_freq "ind_noise_freq"
  114. #define SC_ind_noise_amount "ind_noise_amount"
  115. #define SC_amp_noise_freq "amp_noise_freq"
  116. #define SC_amp_noise_amount "amp_noise_amount"
  117. #define SC_gliss_env "gliss_env"
  118. #define SC_glissando_amount "glissando_amount"
  119. #define SC_fm1_env "fm1_env"
  120. #define SC_fm2_env "fm2_env"
  121. #define SC_fm3_env "fm3_env"
  122. #define SC_fm1_rat "fm1_rat"
  123. #define SC_fm2_rat "fm2_rat"
  124. #define SC_fm3_rat "fm3_rat"
  125. #define SC_fm1_index "fm1_index"
  126. #define SC_fm2_index "fm2_index"
  127. #define SC_fm3_index "fm3_index"
  128. #define SC_index_type "index_type"
  129. #define SC_no_waveshaping "no_waveshaping"
  130. #define SC_reverb_factor "reverb_factor"
  131. #define SC_lp_coeff "lp_coeff"
  132. #define SC_lp_out_coeff "lp_out_coeff"
  133. #define SC_output_scale "output_scale"
  134. #define SC_room_decay "room_decay"
  135. #define SC_output_gain "output_gain"
  136. #define SC_output_mixer "output_mixer"
  137. #define SC_scale_room_decay "scale_room_decay"
  138. #define SC_offset_room_decay "offset_room_decay"
  139. #define SC_scale_damping "scale_dumping"
  140. #define SC_stereo_spread "stereo_spread"
  141. #else /* !HAVE_RUBY */
  142. #define SC_amp_env "amp-env"
  143. #define SC_fm_index "fm-index"
  144. #define SC_reverb_amount "reverb-amount"
  145. #define SC_low_pass "low-pass"
  146. #define SC_periodic_vibrato_rate "periodic-vibrato-rate"
  147. #define SC_periodic_vibrato_amplitude "periodic-vibrato-amplitude"
  148. #define SC_random_vibrato_rate "random-vibrato-rate"
  149. #define SC_random_vibrato_amplitude "random-vibrato-amplitude"
  150. #define SC_noise_freq "noise-freq"
  151. #define SC_noise_amount "noise-amount"
  152. #define SC_ind_noise_freq "ind-noise-freq"
  153. #define SC_ind_noise_amount "ind-noise-amount"
  154. #define SC_amp_noise_freq "amp-noise-freq"
  155. #define SC_amp_noise_amount "amp-noise-amount"
  156. #define SC_gliss_env "gliss-env"
  157. #define SC_glissando_amount "glissando-amount"
  158. #define SC_fm1_env "fm1-env"
  159. #define SC_fm2_env "fm2-env"
  160. #define SC_fm3_env "fm3-env"
  161. #define SC_fm1_rat "fm1-rat"
  162. #define SC_fm2_rat "fm2-rat"
  163. #define SC_fm3_rat "fm3-rat"
  164. #define SC_fm1_index "fm1-index"
  165. #define SC_fm2_index "fm2-index"
  166. #define SC_fm3_index "fm3-index"
  167. #define SC_index_type "index-type"
  168. #define SC_no_waveshaping "no-waveshaping"
  169. #define SC_reverb_factor "reverb-factor"
  170. #define SC_lp_coeff "lp-coeff"
  171. #define SC_lp_out_coeff "lp-out-coeff"
  172. #define SC_output_scale "output-scale"
  173. #define SC_room_decay "room-decay"
  174. #define SC_output_gain "output-gain"
  175. #define SC_output_mixer "output-mixer"
  176. #define SC_scale_room_decay "scale-room-decay"
  177. #define SC_offset_room_decay "offset-room-decay"
  178. #define SC_scale_damping "scale-dumping"
  179. #define SC_stereo_spread "stereo-spread"
  180. #endif /* HAVE_RUBY */
  181. enum {
  182. C_startime,
  183. C_duration,
  184. C_frequency,
  185. C_amplitude,
  186. C_amp_env,
  187. C_fm_index,
  188. C_reverb_amount,
  189. C_degree,
  190. C_distance,
  191. C_periodic_vibrato_rate,
  192. C_periodic_vibrato_amplitude,
  193. C_random_vibrato_rate,
  194. C_random_vibrato_amplitude,
  195. C_noise_freq,
  196. C_noise_amount,
  197. C_ind_noise_freq,
  198. C_ind_noise_amount,
  199. C_amp_noise_freq,
  200. C_amp_noise_amount,
  201. C_gliss_env,
  202. C_glissando_amount,
  203. C_fm1_env,
  204. C_fm2_env,
  205. C_fm3_env,
  206. C_fm1_rat,
  207. C_fm2_rat,
  208. C_fm3_rat,
  209. C_fm1_index,
  210. C_fm2_index,
  211. C_fm3_index,
  212. C_base,
  213. C_index_type,
  214. C_no_waveshaping,
  215. C_low_pass,
  216. C_volume,
  217. C_delay1,
  218. C_delay2,
  219. C_delay3,
  220. C_delay4,
  221. C_doubled,
  222. C_reverb_factor,
  223. C_lp_coeff,
  224. C_lp_out_coeff,
  225. C_output_scale,
  226. C_room_decay,
  227. C_damping,
  228. C_global,
  229. C_predelay,
  230. C_output_gain,
  231. C_output_mixer,
  232. C_scale_room_decay,
  233. C_offset_room_decay,
  234. C_combtuning,
  235. C_allpasstuning,
  236. C_scale_damping,
  237. C_stereo_spread,
  238. C_scaler,
  239. C_size,
  240. C_a0,
  241. C_a1,
  242. NKEYS
  243. };
  244. static char *keywords[NKEYS] = {
  245. SC_startime,
  246. SC_duration,
  247. SC_frequency,
  248. SC_amplitude,
  249. SC_amp_env,
  250. SC_fm_index,
  251. SC_reverb_amount,
  252. SC_degree,
  253. SC_distance,
  254. SC_periodic_vibrato_rate,
  255. SC_periodic_vibrato_amplitude,
  256. SC_random_vibrato_rate,
  257. SC_random_vibrato_amplitude,
  258. SC_noise_freq,
  259. SC_noise_amount,
  260. SC_ind_noise_freq,
  261. SC_ind_noise_amount,
  262. SC_amp_noise_freq,
  263. SC_amp_noise_amount,
  264. SC_gliss_env,
  265. SC_glissando_amount,
  266. SC_fm1_env,
  267. SC_fm2_env,
  268. SC_fm3_env,
  269. SC_fm1_rat,
  270. SC_fm2_rat,
  271. SC_fm3_rat,
  272. SC_fm1_index,
  273. SC_fm2_index,
  274. SC_fm3_index,
  275. SC_base,
  276. SC_index_type,
  277. SC_no_waveshaping,
  278. SC_low_pass,
  279. SC_volume,
  280. SC_delay1,
  281. SC_delay2,
  282. SC_delay3,
  283. SC_delay4,
  284. SC_doubled,
  285. SC_reverb_factor,
  286. SC_lp_coeff,
  287. SC_lp_out_coeff,
  288. SC_output_scale,
  289. SC_room_decay,
  290. SC_damping,
  291. SC_global,
  292. SC_predelay,
  293. SC_output_gain,
  294. SC_output_mixer,
  295. SC_scale_room_decay,
  296. SC_offset_room_decay,
  297. SC_combtuning,
  298. SC_allpasstuning,
  299. SC_scale_damping,
  300. SC_stereo_spread,
  301. SC_scaler,
  302. SC_size,
  303. SC_a0,
  304. SC_a1
  305. };
  306. #if HAVE_RUBY
  307. #define INS_OUTPUT "output"
  308. #define INS_REVERB "reverb"
  309. #define INS_VERBOSE "clm_verbose"
  310. #define INS_LOCSIG_TYPE "clm_locsig_type"
  311. #define INS_DECAY_TIME "clm_decay_time"
  312. #define INS_LIST_BEG "["
  313. #define INS_LIST_END "]"
  314. #define INS_FALSE "false"
  315. #define INS_TRUE "true"
  316. #define INS_SYMBOL_PREFIX ":"
  317. #else
  318. #define INS_OUTPUT "*output*"
  319. #define INS_REVERB "*reverb*"
  320. #define INS_VERBOSE "*clm-verbose*"
  321. #define INS_LOCSIG_TYPE "*clm-locsig-type*"
  322. #define INS_DECAY_TIME "*clm-decay-time*"
  323. #define INS_LIST_BEG "'("
  324. #define INS_LIST_END ")"
  325. #define INS_FALSE "#f"
  326. #define INS_TRUE "#t"
  327. #define INS_SYMBOL_PREFIX "'"
  328. #endif
  329. /* utility functions */
  330. static mus_float_t *array2array(mus_float_t *list, int len);
  331. static bool array_equal_p(mus_float_t *env1, int len1,
  332. mus_float_t *env2, int len2);
  333. static int feq (mus_float_t x, int i);
  334. static char *format_array(mus_float_t *line, int size);
  335. static bool get_global_boolean(const char *name, bool def);
  336. static mus_float_t get_global_float(const char *name, mus_float_t def);
  337. static int get_global_int(const char *name, int def);
  338. static mus_any *get_global_mus_gen(const char *name);
  339. static int ins_message(const char *fmt,...);
  340. static int *int_array2array(int *list, int len);
  341. static bool prime_p(int x);
  342. static mus_float_t *xen_list2array(XEN list);
  343. static int *xen_list2iarray(XEN list);
  344. /* fcomb generator */
  345. static char *fcomb_describe(mus_any *ptr);
  346. static bool fcomb_equal_p(mus_any *p1, mus_any *p2);
  347. static int fcomb_free(mus_any *ptr);
  348. static mus_long_t fcomb_length(mus_any *ptr);
  349. static mus_float_t fcomb_scaler(mus_any *ptr);
  350. /* XEN fcomb */
  351. static XEN c_fcomb(XEN gen, XEN input);
  352. static XEN c_fcomb_p(XEN gen);
  353. static XEN c_make_fcomb(XEN args);
  354. /* instruments */
  355. #if HAVE_FORTH
  356. static void c_fm_violin(XEN args);
  357. static void c_freeverb(XEN args);
  358. static void c_jc_reverb(XEN args);
  359. static void c_nrev(XEN args);
  360. #else
  361. static XEN c_fm_violin(XEN args);
  362. static XEN c_freeverb(XEN args);
  363. static XEN c_jc_reverb(XEN args);
  364. static XEN c_nrev(XEN args);
  365. #endif
  366. static XEN allkeys[NKEYS];
  367. static void
  368. init_keywords(void)
  369. {
  370. int i;
  371. for (i = 0; i < NKEYS; i++)
  372. allkeys[i] = XEN_MAKE_KEYWORD(keywords[i]);
  373. }
  374. static mus_any *
  375. get_global_mus_gen(const char *name)
  376. {
  377. if (XEN_DEFINED_P(name)) {
  378. XEN value;
  379. value = XEN_NAME_AS_C_STRING_TO_VALUE(name);
  380. if (mus_xen_p(value))
  381. return (XEN_TO_MUS_ANY(value));
  382. }
  383. return (NULL);
  384. }
  385. static bool
  386. get_global_boolean(const char *name, bool def)
  387. {
  388. if (XEN_DEFINED_P(name)) {
  389. XEN value;
  390. value = XEN_NAME_AS_C_STRING_TO_VALUE(name);
  391. if (XEN_BOOLEAN_P(value))
  392. return (XEN_TO_C_BOOLEAN(value));
  393. }
  394. return (def);
  395. }
  396. static int
  397. get_global_int(const char *name, int def)
  398. {
  399. if (XEN_DEFINED_P(name)) {
  400. XEN value;
  401. value = XEN_NAME_AS_C_STRING_TO_VALUE(name);
  402. if (XEN_NUMBER_P(value))
  403. return (XEN_TO_C_INT(value));
  404. }
  405. return (def);
  406. }
  407. static mus_float_t
  408. get_global_float(const char *name, mus_float_t def)
  409. {
  410. if (XEN_DEFINED_P(name)) {
  411. XEN value;
  412. value = XEN_NAME_AS_C_STRING_TO_VALUE(name);
  413. if (XEN_NUMBER_P(value))
  414. return (XEN_TO_C_DOUBLE(value));
  415. }
  416. return (def);
  417. }
  418. /*
  419. * Return mus_float_t array initialized with contents of XEN list.
  420. * (mus_make_env())
  421. */
  422. static mus_float_t *
  423. xen_list2array(XEN list)
  424. {
  425. int len, i = 0;
  426. mus_float_t *flist;
  427. XEN lst;
  428. len = XEN_LIST_LENGTH(list);
  429. if (len == 0)
  430. return (NULL);
  431. flist = malloc(len * sizeof(mus_float_t));
  432. if (flist == NULL) {
  433. INS_NO_MEMORY_ERROR("xen_list2array");
  434. /* NOTREACHED */
  435. return (NULL);
  436. }
  437. for (i = 0, lst = XEN_COPY_ARG(list); i < len; i++, lst = XEN_CDR(lst))
  438. flist[i] = XEN_TO_C_DOUBLE(XEN_CAR(lst));
  439. return (flist);
  440. }
  441. /*
  442. * Return int array initialized with contents of XEN list.
  443. * (mus_make_mixer())
  444. */
  445. static int *
  446. xen_list2iarray(XEN list)
  447. {
  448. int len, i = 0;
  449. int *ilist;
  450. XEN lst;
  451. len = XEN_LIST_LENGTH(list);
  452. if (len == 0)
  453. return (NULL);
  454. ilist = malloc(len * sizeof(int));
  455. if (ilist == NULL) {
  456. INS_NO_MEMORY_ERROR("xen_list2iarray");
  457. /* NOTREACHED */
  458. return (NULL);
  459. }
  460. for (i = 0, lst = XEN_COPY_ARG(list); i < len; i++, lst = XEN_CDR(lst))
  461. ilist[i] = XEN_TO_C_INT(XEN_CAR(lst));
  462. return (ilist);
  463. }
  464. /*
  465. * Return mus_float_t array initialized with contents of mus_float_t list.
  466. * (mus_make_env())
  467. */
  468. static mus_float_t *
  469. array2array(mus_float_t *list, int len)
  470. {
  471. int i = 0;
  472. mus_float_t *flist;
  473. if (len == 0)
  474. return (NULL);
  475. flist = malloc(len * sizeof(mus_float_t));
  476. if (flist == NULL) {
  477. INS_NO_MEMORY_ERROR("array2array");
  478. /* NOTREACHED */
  479. return (NULL);
  480. }
  481. for (i = 0; i < len; i++)
  482. flist[i] = (mus_float_t)list[i];
  483. return (flist);
  484. }
  485. /*
  486. * Return int array initialized with contents of int list.
  487. * (mus_make_mixer())
  488. */
  489. static int *
  490. int_array2array(int *list, int len)
  491. {
  492. int i = 0;
  493. int *ilist;
  494. if (len == 0)
  495. return (NULL);
  496. ilist = malloc(len * sizeof(int));
  497. if (ilist == NULL) {
  498. INS_NO_MEMORY_ERROR("int_array2array");
  499. /* NOTREACHED */
  500. return (NULL);
  501. }
  502. for (i = 0; i < len; i++)
  503. ilist[i] = (int)list[i];
  504. return (ilist);
  505. }
  506. /*
  507. * ins_fm_violin: easy_case
  508. */
  509. static bool
  510. array_equal_p(mus_float_t *env1, int len1, mus_float_t *env2, int len2)
  511. {
  512. if (env1 != NULL && env2 != NULL && len1 == len2) {
  513. int i;
  514. for (i = 0; i < len1; i++)
  515. if (env1[i] != env2[i])
  516. return (false);
  517. return (true);
  518. }
  519. return (false);
  520. }
  521. /*
  522. * Print message in listener.
  523. */
  524. #if HAVE_SCHEME
  525. #define INS_COMMENT_STRING ";;"
  526. #else
  527. #define INS_COMMENT_STRING XEN_COMMENT_STRING
  528. #endif
  529. static int
  530. ins_message(const char *fmt,...)
  531. {
  532. int len, result;
  533. va_list ap;
  534. char *s;
  535. len = strlen(fmt) + 128;
  536. s = malloc(len * sizeof(char));
  537. if (s == NULL) {
  538. INS_NO_MEMORY_ERROR("ins_message");
  539. /* NOTREACHED */
  540. return (-1);
  541. }
  542. va_start(ap, fmt);
  543. result = vsnprintf(s, len, fmt, ap);
  544. va_end(ap);
  545. if (XEN_PROVIDED_P("snd") && !XEN_PROVIDED_P("snd-nogui"))
  546. mus_print(INS_COMMENT_STRING " %s", s);
  547. else
  548. fprintf(stdout, INS_COMMENT_STRING " %s", s);
  549. free(s);
  550. return (result);
  551. }
  552. static int
  553. feq(mus_float_t x, int i)
  554. {
  555. return (fabs(x - i) < 0.00001);
  556. }
  557. static bool
  558. prime_p(int x)
  559. {
  560. if (x == 2)
  561. return (true);
  562. if (x % 2) {
  563. int i;
  564. for (i = 3; i < sqrt(x); i += 2)
  565. if ((x % i) == 0)
  566. return (false);
  567. return (true);
  568. }
  569. return (false);
  570. }
  571. #define INS_FMT_SIZE 128
  572. static char *
  573. format_array(mus_float_t *line, int size)
  574. {
  575. int i, lim;
  576. char *s, *t;
  577. lim = size;
  578. s = NULL;
  579. if (lim > mus_array_print_length())
  580. lim = mus_array_print_length();
  581. s = calloc(INS_FMT_SIZE * lim * 2, sizeof(char));
  582. if (s == NULL) {
  583. INS_NO_MEMORY_ERROR("format_array");
  584. /* NOTREACHED */
  585. return (NULL);
  586. }
  587. if (line == NULL)
  588. return (strcpy(s, "nil"));
  589. strcpy(s, "[");
  590. for (i = 0; i < lim - 1; i++) {
  591. t = mus_format("%.3f ", line[i]);
  592. strcat(s, t);
  593. free(t);
  594. }
  595. t = mus_format("%.3f%s]", line[i], (size > lim) ? "..." : "");
  596. strcat(s, t);
  597. free(t);
  598. return (s);
  599. }
  600. /* --- fcomb --- */
  601. typedef struct {
  602. mus_any_class *core;
  603. int loc;
  604. int size; /* mus_length(gen) */
  605. mus_float_t *line; /* mus_data(gen) */
  606. mus_float_t xs[2]; /* a0, a1; mus_xcoeff(gen, 0 or 1) */
  607. mus_float_t xscl; /* mus_scaler(gen) */
  608. mus_float_t x1;
  609. } fcomb;
  610. static int MUS_FCOMB = 0;
  611. int
  612. mus_fcomb_p(mus_any *ptr)
  613. {
  614. return (ptr != NULL && mus_type(ptr) == MUS_FCOMB);
  615. }
  616. #define INS_DESCRIBE_SIZE 2048
  617. static char *
  618. fcomb_describe(mus_any *ptr)
  619. {
  620. char *s, *t;
  621. fcomb *gen;
  622. gen = (fcomb *)ptr;
  623. t = format_array(gen->line, gen->size);
  624. s = mus_format("fcomb: scaler: "
  625. "%.3f, a0: %.3f, a1: %.3f, x1: %.3f, line[%d]: %s",
  626. gen->xscl, gen->xs[0], gen->xs[1], gen->x1, gen->size, t);
  627. free(t);
  628. return (s);
  629. }
  630. static bool
  631. fcomb_equal_p(mus_any *p1, mus_any *p2)
  632. {
  633. fcomb *g1, *g2;
  634. g1 = (fcomb *)p1;
  635. g2 = (fcomb *)p2;
  636. return (mus_fcomb_p(p1) && ((p1 == p2) ||
  637. (mus_fcomb_p(p2) &&
  638. g1->xs[0] == g2->xs[0] &&
  639. g1->xs[1] == g2->xs[1] &&
  640. g1->x1 == g2->x1)));
  641. }
  642. static mus_long_t
  643. fcomb_length(mus_any *ptr)
  644. {
  645. fcomb *gen;
  646. gen = (fcomb *)ptr;
  647. return ((mus_long_t)(gen->size));
  648. }
  649. static mus_float_t
  650. fcomb_scaler(mus_any *ptr)
  651. {
  652. fcomb *gen;
  653. gen = (fcomb *)ptr;
  654. return (gen->xscl);
  655. }
  656. static int
  657. fcomb_free(mus_any *ptr)
  658. {
  659. fcomb *gen;
  660. gen = (fcomb *)ptr;
  661. if (gen != NULL) {
  662. if (gen->line != NULL)
  663. free(gen->line);
  664. gen->line = NULL;
  665. free(gen);
  666. }
  667. return (0);
  668. }
  669. /*
  670. * Now the actual run-time code executed by fcomb the extra "ignored"
  671. * argument is for the run method
  672. */
  673. mus_float_t
  674. mus_fcomb(mus_any *ptr, mus_float_t input,
  675. mus_float_t ignored __attribute__((unused)))
  676. {
  677. fcomb *gen;
  678. mus_float_t tap_result, filter_result;
  679. gen = (fcomb *)ptr;
  680. tap_result = gen->line[gen->loc];
  681. filter_result = (gen->xs[0] * tap_result) + (gen->xs[1] * gen->x1);
  682. gen->x1 = tap_result;
  683. gen->line[gen->loc] = input + filter_result * gen->xscl;
  684. gen->loc++;
  685. if (gen->loc >= gen->size)
  686. gen->loc = 0;
  687. return (tap_result);
  688. }
  689. /*
  690. * Now a function to make a new generator.
  691. */
  692. mus_any *
  693. mus_make_fcomb(mus_float_t scaler, int size, mus_float_t a0, mus_float_t a1)
  694. {
  695. fcomb *gen;
  696. int i;
  697. gen = calloc(1, sizeof(fcomb));
  698. if (gen == NULL) {
  699. INS_NO_MEMORY_ERROR("mus_make_fcomb");
  700. /* NOTREACHED */
  701. return (NULL);
  702. }
  703. gen->line = calloc(size, sizeof(mus_float_t));
  704. if (gen->line == NULL) {
  705. INS_NO_MEMORY_ERROR("mus_make_fcomb");
  706. /* NOTREACHED */
  707. return (NULL);
  708. }
  709. for (i = 0; i < size; i++)
  710. gen->line[i] = 0.0;
  711. MUS_FCOMB = mus_make_generator_type();
  712. gen->core = mus_make_generator(MUS_FCOMB, "fcomb",
  713. fcomb_free, fcomb_describe, fcomb_equal_p);
  714. if (gen->core == NULL) {
  715. INS_NO_MEMORY_ERROR("mus_make_fcomb");
  716. /* NOTREACHED */
  717. return (NULL);
  718. }
  719. gen->loc = 0;
  720. gen->xscl = scaler;
  721. gen->x1 = 0.0;
  722. gen->xs[0] = a0;
  723. gen->xs[1] = a1;
  724. gen->size = size;
  725. mus_generator_set_length(gen->core, fcomb_length);
  726. mus_generator_set_scaler(gen->core, fcomb_scaler);
  727. return ((mus_any *)gen);
  728. }
  729. /*
  730. * That is the end of the C side; the rest ties this generator into
  731. * Scheme/Ruby/Forth via the Xen package in Snd's case, it's actually
  732. * not needed because the generator is only called from C.
  733. */
  734. #define h_make_fcomb_args "\
  735. keyword arguments with default values:\n\
  736. :scaler 1.0\n\
  737. :size 1\n\
  738. :a0 0.0\n\
  739. :a1 0.0\n\
  740. Return new fcomb generator."
  741. #if HAVE_RUBY
  742. #define S_make_fcomb "make_fcomb"
  743. #else
  744. #define S_make_fcomb "make-fcomb"
  745. #endif
  746. #if HAVE_RUBY
  747. #define H_make_fcomb S_make_fcomb "(*args)\n" h_make_fcomb_args
  748. #elif HAVE_FORTH
  749. #define H_make_fcomb S_make_fcomb " ( args -- gen )\n" h_make_fcomb_args
  750. #else /* HAVE_SCHEME */
  751. #define H_make_fcomb "(" S_make_fcomb " . args)\n" h_make_fcomb_args
  752. #endif
  753. #define MAX_TABLE_SIZE (1024 * 1024 * 20)
  754. static XEN
  755. c_make_fcomb(XEN args)
  756. {
  757. #define FCOMB_LAST_KEY 4
  758. int i, keyn, argn, vals, lst_len, size;
  759. mus_float_t scaler, a0, a1;
  760. XEN kargs[FCOMB_LAST_KEY * 2], keys[FCOMB_LAST_KEY];
  761. int orig_arg[FCOMB_LAST_KEY] = {0};
  762. mus_any *ge;
  763. argn = 0;
  764. lst_len = XEN_LIST_LENGTH(args);
  765. size = 1;
  766. scaler = 1.0;
  767. a0 = a1 = 0.0;
  768. keys[argn++] = allkeys[C_scaler];
  769. keys[argn++] = allkeys[C_size];
  770. keys[argn++] = allkeys[C_a0];
  771. keys[argn++] = allkeys[C_a1];
  772. for (i = 0; i < FCOMB_LAST_KEY * 2; i++)
  773. kargs[i] = XEN_UNDEFINED;
  774. for (i = 0; i < lst_len; i++)
  775. kargs[i] = XEN_LIST_REF(args, i);
  776. vals = mus_optkey_unscramble(S_make_fcomb, argn, keys, kargs, orig_arg);
  777. if (vals > 0) {
  778. keyn = 0;
  779. scaler = mus_optkey_to_float(keys[keyn], S_make_fcomb,
  780. orig_arg[keyn], scaler);
  781. keyn++;
  782. size = mus_optkey_to_int(keys[keyn], S_make_fcomb,
  783. orig_arg[keyn], size);
  784. if (size < 0)
  785. XEN_OUT_OF_RANGE_ERROR(S_make_fcomb, orig_arg[keyn],
  786. keys[keyn], "size < 0?");
  787. if (size > MAX_TABLE_SIZE)
  788. XEN_OUT_OF_RANGE_ERROR(S_make_fcomb, orig_arg[keyn],
  789. keys[keyn], "size too large");
  790. keyn++;
  791. a0 = mus_optkey_to_float(keys[keyn], S_make_fcomb,
  792. orig_arg[keyn], a0);
  793. keyn++;
  794. a1 = mus_optkey_to_float(keys[keyn], S_make_fcomb,
  795. orig_arg[keyn], a1);
  796. }
  797. ge = mus_make_fcomb(scaler, size, a0, a1);
  798. if (ge) {
  799. fcomb *g;
  800. mus_xen *fc;
  801. XEN v1, v2;
  802. g = (fcomb *)ge;
  803. /* wrapper set v->dont_free = true */
  804. v1 = xen_make_vct_wrapper(size, g->line);
  805. v2 = xen_make_vct_wrapper(2, g->xs);
  806. fc = mus_any_to_mus_xen_with_two_vcts(ge, v1, v2);
  807. return (mus_xen_to_object(fc));
  808. }
  809. return (XEN_FALSE);
  810. }
  811. #define S_fcomb_p "fcomb?"
  812. #define h_fcomb_p_doc "\
  813. Return " INS_TRUE " if GEN is an fcomb generator, otherwise " INS_FALSE "."
  814. #if HAVE_RUBY
  815. #define H_fcomb_p S_fcomb_p "(gen) " h_fcomb_p_doc
  816. #elif HAVE_FORTH
  817. #define H_fcomb_p S_fcomb_p " ( gen -- f ) " h_fcomb_p_doc
  818. #else /* HAVE_SCHEME */
  819. #define H_fcomb_p "(" S_fcomb_p " gen) " h_fcomb_p_doc
  820. #endif
  821. #define XEN_FCOMB_P(obj) \
  822. (mus_xen_p(obj) && mus_fcomb_p(XEN_TO_MUS_ANY(obj)))
  823. static XEN
  824. c_fcomb_p(XEN obj)
  825. {
  826. return (C_TO_XEN_BOOLEAN(XEN_FCOMB_P(obj)));
  827. }
  828. #define S_fcomb "fcomb"
  829. #define h_fcomb_doc "Return result of running fcomb generator."
  830. #if HAVE_RUBY
  831. #define H_fcomb S_fcomb "(gen, input=0.0) " h_fcomb_doc
  832. #elif HAVE_FORTH
  833. #define H_fcomb S_fcomb " ( gen input=0.0 -- res ) " h_fcomb_doc
  834. #else /* HAVE_SCHEME */
  835. #define H_fcomb "(" S_fcomb " gen (input 0.0)) " h_fcomb_doc
  836. #endif
  837. static XEN
  838. c_fcomb(XEN gen, XEN input)
  839. {
  840. mus_any *ge;
  841. mus_float_t fm;
  842. fm = 0.0;
  843. ge = XEN_TO_MUS_ANY(gen);
  844. XEN_ASSERT_TYPE(mus_fcomb_p(ge), gen, 1, S_fcomb, "an fcomb");
  845. if (XEN_BOUND_P(input))
  846. fm = XEN_TO_C_DOUBLE(input);
  847. return (C_TO_XEN_DOUBLE(mus_fcomb(ge, fm, 0.0)));
  848. }
  849. /* --- instruments --- */
  850. #if HAVE_RUBY
  851. #define S_fm_violin "fm_violin"
  852. #define S_jc_reverb "jc_reverb"
  853. #else
  854. #define S_fm_violin "fm-violin"
  855. #define S_jc_reverb "jc-reverb"
  856. #endif
  857. #define S_nrev "nrev"
  858. #define S_freeverb "freeverb"
  859. mus_long_t
  860. ins_fm_violin(mus_float_t start, mus_float_t dur, mus_float_t freq,
  861. mus_float_t amp, mus_float_t fm_index, mus_float_t *amp_env,
  862. int amp_len, mus_float_t periodic_vibrato_rate,
  863. mus_float_t periodic_vibrato_amp, mus_float_t random_vibrato_rate,
  864. mus_float_t random_vibrato_amp, mus_float_t noise_freq,
  865. mus_float_t noise_amount, mus_float_t ind_noise_freq,
  866. mus_float_t ind_noise_amount, mus_float_t amp_noise_freq,
  867. mus_float_t amp_noise_amount, mus_float_t *gliss_env, int gliss_len,
  868. mus_float_t gliss_amount, mus_float_t *fm1_env, int fm1_len,
  869. mus_float_t *fm2_env, int fm2_len, mus_float_t *fm3_env, int fm3_len,
  870. mus_float_t fm1_rat, mus_float_t fm2_rat, mus_float_t fm3_rat,
  871. mus_float_t fm1_index, mus_float_t fm2_index, mus_float_t fm3_index,
  872. mus_float_t base, mus_float_t degree, mus_float_t distance,
  873. mus_float_t reverb_amount, bool index_type, bool no_waveshaping,
  874. mus_any *out, mus_any *rev, mus_interp_t mode)
  875. {
  876. mus_long_t i, beg, len;
  877. int out_chans, rev_chans;
  878. bool vln, easy_case, modulate;
  879. mus_float_t frq_scl, maxdev, index1, index2, index3, vib;
  880. mus_float_t logfrq, sqrtfrq, norm, mod;
  881. mus_float_t *partials = NULL;
  882. mus_float_t fuzz, ind_fuzz, amp_fuzz;
  883. mus_any *carrier, *fmosc1, *fmosc2 = NULL, *fmosc3 = NULL;
  884. mus_any *ampf, *indf1, *indf2 = NULL, *indf3 = NULL, *pervib;
  885. mus_any *fm_noi = NULL, *ind_noi = NULL, *amp_noi = NULL;
  886. mus_any *ranvib, *frqf = NULL, *loc;
  887. out_chans = 1;
  888. rev_chans = 0;
  889. vln = true;
  890. easy_case = modulate = false;
  891. frq_scl = maxdev = index1 = index2 = index3 = vib = 0.0;
  892. logfrq = sqrtfrq = norm = mod = fuzz = 0.0;
  893. ind_fuzz = amp_fuzz = 1.0;
  894. beg = mus_seconds_to_samples(start);
  895. len = beg + mus_seconds_to_samples(dur);
  896. frq_scl = mus_hz_to_radians(freq);
  897. modulate = (fm_index != 0.0);
  898. maxdev = frq_scl * fm_index;
  899. logfrq = log(freq);
  900. sqrtfrq = sqrt(freq);
  901. vln = index_type; /* true: violin, false: cello */
  902. if (fm1_index != 0.0)
  903. index1 = fm1_index;
  904. else {
  905. index1 = vln ?
  906. (maxdev * 5.0 / logfrq) :
  907. (maxdev * 7.5 / logfrq);
  908. if (index1 > M_PI)
  909. index1 = M_PI;
  910. }
  911. if (fm2_index != 0.0)
  912. index2 = fm2_index;
  913. else {
  914. index2 = vln ?
  915. (maxdev * 3.0 * (8.5 - logfrq) / (3.0 + freq * 0.001)) :
  916. (maxdev * 3.0 * 15.0 / sqrtfrq);
  917. if (index2 > M_PI)
  918. index2 = M_PI;
  919. }
  920. if (fm3_index != 0.0)
  921. index3 = fm3_index;
  922. else {
  923. index3 = vln ? (maxdev * 4.0 / sqrtfrq) :
  924. (maxdev * 8.0 / sqrtfrq);
  925. if (index3 > M_PI)
  926. index3 = M_PI;
  927. }
  928. easy_case = (noise_amount == 0.0 && !no_waveshaping &&
  929. array_equal_p(fm1_env, fm1_len, fm2_env, fm2_len) &&
  930. array_equal_p(fm1_env, fm1_len, fm3_env, fm3_len) &&
  931. feq(fm1_rat, (int)floor(fm1_rat)) &&
  932. feq(fm2_rat, (int)floor(fm2_rat)) &&
  933. feq(fm3_rat, (int)floor(fm3_rat)));
  934. if (easy_case && modulate)
  935. norm = 1.0;
  936. else
  937. norm = index1;
  938. carrier = mus_make_oscil(freq, 0.0);
  939. if (modulate) {
  940. if (easy_case) {
  941. int nparts;
  942. nparts = (int)floor(fm1_rat);
  943. if ((int)floor(fm2_rat) > nparts)
  944. nparts = (int)floor(fm2_rat);
  945. if ((int)floor(fm3_rat) > nparts)
  946. nparts = (int)floor(fm3_rat);
  947. nparts++;
  948. partials = calloc(nparts, sizeof(mus_float_t));
  949. partials[(int)(fm1_rat)] = index1;
  950. partials[(int)(fm2_rat)] = index2;
  951. partials[(int)(fm3_rat)] = index3;
  952. fmosc1 = mus_make_polyshape(freq * fm1_rat, 0.0,
  953. mus_partials_to_polynomial(nparts, partials, 1),
  954. nparts, MUS_CHEBYSHEV_FIRST_KIND);
  955. } else
  956. fmosc1 = mus_make_oscil(freq * fm1_rat, 0.0);
  957. indf1 = mus_make_env(fm1_env, fm1_len / 2, norm, 0.0, 1.0,
  958. dur, 0, NULL);
  959. if (!easy_case) {
  960. fmosc2 = mus_make_oscil(freq * fm2_rat, 0.0);
  961. fmosc3 = mus_make_oscil(freq * fm3_rat, 0.0);
  962. indf2 = mus_make_env(fm2_env, fm2_len / 2, index2,
  963. 0.0, 1.0, dur, 0, NULL);
  964. indf3 = mus_make_env(fm3_env, fm3_len / 2, index3,
  965. 0.0, 1.0, dur, 0, NULL);
  966. }
  967. }
  968. ampf = mus_make_env(amp_env, amp_len / 2, amp, 0.0, base, dur, 0, NULL);
  969. frqf = mus_make_env(gliss_env, gliss_len / 2, gliss_amount * frq_scl,
  970. 0.0, 1.0, dur, 0, NULL);
  971. pervib = mus_make_triangle_wave(periodic_vibrato_rate,
  972. periodic_vibrato_amp * frq_scl, 0.0);
  973. ranvib = mus_make_rand_interp(random_vibrato_rate,
  974. random_vibrato_amp * frq_scl);
  975. if (noise_amount != 0.0)
  976. fm_noi = mus_make_rand(noise_freq, noise_amount * M_PI);
  977. if (ind_noise_amount != 0.0 && ind_noise_freq != 0.0)
  978. ind_noi = mus_make_rand_interp(ind_noise_freq,
  979. ind_noise_amount);
  980. if (amp_noise_amount != 0.0 && amp_noise_freq != 0.0)
  981. amp_noi = mus_make_rand_interp(amp_noise_freq,
  982. amp_noise_amount);
  983. if (degree == 0.0)
  984. degree = mus_random(90.0);
  985. if (out)
  986. out_chans = mus_channels(out);
  987. if (rev)
  988. rev_chans = mus_channels(rev);
  989. loc = mus_make_locsig(degree, distance, reverb_amount,
  990. out_chans, out, rev_chans, rev, mode);
  991. for (i = beg; i < len; i++) {
  992. if (fm_noi)
  993. fuzz = mus_rand(fm_noi, 0.0);
  994. vib = mus_env(frqf) + mus_triangle_wave(pervib, 0.0) +
  995. mus_rand_interp(ranvib, 0.0);
  996. if (ind_noi)
  997. ind_fuzz = 1.0 + mus_rand_interp(ind_noi, 0.0);
  998. if (amp_noi)
  999. amp_fuzz = 1.0 + mus_rand_interp(amp_noi, 0.0);
  1000. if (modulate) {
  1001. if (easy_case)
  1002. mod = mus_env(indf1) *
  1003. mus_polyshape_unmodulated(fmosc1, vib);
  1004. else
  1005. mod = mus_env(indf1) * mus_oscil(fmosc1,
  1006. fuzz + fm1_rat * vib, 0.0) +
  1007. mus_env(indf2) * mus_oscil(fmosc2,
  1008. fuzz + fm2_rat * vib, 0.0) +
  1009. mus_env(indf3) * mus_oscil(fmosc3,
  1010. fuzz + fm3_rat * vib, 0.0);
  1011. }
  1012. mus_locsig(loc, i, mus_env(ampf) * amp_fuzz *
  1013. mus_oscil(carrier, vib + ind_fuzz * mod, 0.0));
  1014. }
  1015. mus_free(pervib);
  1016. mus_free(ranvib);
  1017. mus_free(carrier);
  1018. mus_free(fmosc1);
  1019. mus_free(ampf);
  1020. mus_free(indf1);
  1021. mus_free(loc);
  1022. if (fm_noi)
  1023. mus_free(fm_noi);
  1024. if (ind_noi)
  1025. mus_free(ind_noi);
  1026. if (amp_noi)
  1027. mus_free(amp_noi);
  1028. if (frqf)
  1029. mus_free(frqf);
  1030. if (fmosc2)
  1031. mus_free(fmosc2);
  1032. if (fmosc3)
  1033. mus_free(fmosc3);
  1034. if (indf2)
  1035. mus_free(indf2);
  1036. if (indf3)
  1037. mus_free(indf3);
  1038. if (partials)
  1039. free(partials);
  1040. return (i);
  1041. }
  1042. #define JC_WARN "is not set up for doubled reverb in quad"
  1043. mus_long_t
  1044. ins_jc_reverb(mus_float_t start, mus_float_t dur, mus_float_t volume,
  1045. bool low_pass, bool doubled, mus_float_t delay1, mus_float_t delay2,
  1046. mus_float_t delay3, mus_float_t delay4, mus_float_t *amp_env, int amp_len,
  1047. mus_any *out, mus_any *rev)
  1048. {
  1049. mus_long_t i, beg, len;
  1050. int del_len, chans, rev_chans;
  1051. bool chan2, chan4;
  1052. mus_float_t delA, delB;
  1053. mus_float_t allpass_sum, comb_sum, comb_sum_1, comb_sum_2, all_sums;
  1054. mus_any *allpass1, *allpass2, *allpass3;
  1055. mus_any *comb1, *comb2, *comb3, *comb4;
  1056. mus_any *outdel1, *outdel2 = NULL, *outdel3 = NULL, *outdel4 = NULL;
  1057. mus_any *env_a = NULL;
  1058. del_len = chans = rev_chans = 0;
  1059. chan2 = chan4 = false;
  1060. delA = delB = 0.0;
  1061. allpass_sum = comb_sum = comb_sum_1 = comb_sum_2 = all_sums = 0.0;
  1062. beg = mus_seconds_to_samples(start);
  1063. if (dur > 0.0)
  1064. len = beg + mus_seconds_to_samples(dur);
  1065. else
  1066. len = beg + mus_seconds_to_samples(1.0) +
  1067. mus_sound_frames(mus_file_name(rev));
  1068. chans = mus_channels(out);
  1069. rev_chans = mus_channels(rev);
  1070. allpass1 = mus_make_all_pass(-0.7, 0.7, 1051, NULL, 1051,
  1071. MUS_INTERP_LINEAR);
  1072. allpass2 = mus_make_all_pass(-0.7, 0.7, 337, NULL, 337,
  1073. MUS_INTERP_LINEAR);
  1074. allpass3 = mus_make_all_pass(-0.7, 0.7, 113, NULL, 113,
  1075. MUS_INTERP_LINEAR);
  1076. comb1 = mus_make_comb(0.742, 4799, NULL, 4799, MUS_INTERP_LINEAR);
  1077. comb2 = mus_make_comb(0.733, 4999, NULL, 4999, MUS_INTERP_LINEAR);
  1078. comb3 = mus_make_comb(0.715, 5399, NULL, 5399, MUS_INTERP_LINEAR);
  1079. comb4 = mus_make_comb(0.697, 5801, NULL, 5801, MUS_INTERP_LINEAR);
  1080. if (chans > 1)
  1081. chan2 = true;
  1082. if (chans == 4)
  1083. chan4 = true;
  1084. del_len = mus_seconds_to_samples(delay1);
  1085. outdel1 = mus_make_delay(del_len, NULL, del_len, MUS_INTERP_LINEAR);
  1086. if (chan2) {
  1087. del_len = mus_seconds_to_samples(delay2);
  1088. outdel2 = mus_make_delay(del_len, NULL, del_len,
  1089. MUS_INTERP_LINEAR);
  1090. }
  1091. if (doubled || chan4) {
  1092. del_len = mus_seconds_to_samples(delay3);
  1093. outdel3 = mus_make_delay(del_len, NULL, del_len,
  1094. MUS_INTERP_LINEAR);
  1095. }
  1096. if (chan4 || (doubled && chan2)) {
  1097. del_len = mus_seconds_to_samples(delay4);
  1098. outdel4 = mus_make_delay(del_len, NULL, del_len,
  1099. MUS_INTERP_LINEAR);
  1100. }
  1101. if (amp_env)
  1102. env_a = mus_make_env(amp_env, amp_len / 2, volume, 0.0, 1.0,
  1103. dur, 0, NULL);
  1104. if (doubled && chan4)
  1105. INS_MISC_ERROR(S_jc_reverb, JC_WARN);
  1106. for (i = beg; i < len; i++) {
  1107. int j;
  1108. mus_float_t ho;
  1109. for (j = 0, ho = 0.0; j < rev_chans; j++)
  1110. ho += mus_in_any(i, j, rev);
  1111. allpass_sum = mus_all_pass_unmodulated(allpass3,
  1112. mus_all_pass_unmodulated(allpass2,
  1113. mus_all_pass_unmodulated(allpass1, ho)));
  1114. comb_sum_2 = comb_sum_1;
  1115. comb_sum_1 = comb_sum;
  1116. comb_sum = mus_comb_unmodulated(comb1, allpass_sum) +
  1117. mus_comb_unmodulated(comb2, allpass_sum) +
  1118. mus_comb_unmodulated(comb3, allpass_sum) +
  1119. mus_comb_unmodulated(comb4, allpass_sum);
  1120. if (low_pass)
  1121. all_sums = 0.25 * (comb_sum + comb_sum_2) +
  1122. 0.5 * comb_sum_1;
  1123. else
  1124. all_sums = comb_sum;
  1125. delA = mus_delay_unmodulated(outdel1, all_sums);
  1126. if (doubled)
  1127. delA += mus_delay_unmodulated(outdel3, all_sums);
  1128. if (env_a)
  1129. volume = mus_env(env_a);
  1130. mus_out_any(i, delA * volume, 0, out);
  1131. if (chan2) {
  1132. delB = mus_delay_unmodulated(outdel2, all_sums);
  1133. if (doubled)
  1134. delB += mus_delay_unmodulated(outdel4,
  1135. all_sums);
  1136. mus_out_any(i, delB * volume, 1, out);
  1137. if (chan4) {
  1138. mus_out_any(i, volume *
  1139. mus_delay_unmodulated(outdel3, all_sums),
  1140. 2, out);
  1141. mus_out_any(i, volume *
  1142. mus_delay_unmodulated(outdel4, all_sums),
  1143. 3, out);
  1144. }
  1145. }
  1146. }
  1147. mus_free(allpass1);
  1148. mus_free(allpass2);
  1149. mus_free(allpass3);
  1150. mus_free(comb1);
  1151. mus_free(comb2);
  1152. mus_free(comb3);
  1153. mus_free(comb4);
  1154. mus_free(outdel1);
  1155. if (outdel2)
  1156. mus_free(outdel2);
  1157. if (outdel3)
  1158. mus_free(outdel3);
  1159. if (outdel4)
  1160. mus_free(outdel4);
  1161. if (env_a)
  1162. mus_free(env_a);
  1163. return (i);
  1164. }
  1165. mus_long_t
  1166. ins_nrev(mus_float_t start, mus_float_t dur, mus_float_t reverb_factor,
  1167. mus_float_t lp_coeff, mus_float_t lp_out_coeff, mus_float_t output_scale,
  1168. mus_float_t volume, mus_float_t *amp_env, int amp_len,
  1169. mus_any *out, mus_any *rev)
  1170. {
  1171. mus_long_t i, beg, len;
  1172. int chans, rev_chans, val;
  1173. int dly_len[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113,
  1174. 37, 59, 53, 43, 37, 29, 19};
  1175. mus_float_t srscale;
  1176. mus_float_t sample_a, sample_b, sample_c, sample_d;
  1177. mus_float_t inrev, outrev;
  1178. mus_any *allpass1, *allpass2, *allpass3, *allpass4;
  1179. mus_any *allpass5, *allpass6, *allpass7, *allpass8;
  1180. mus_any *comb1, *comb2, *comb3, *comb4, *comb5, *comb6;
  1181. mus_any *low, *low_a, *low_b, *low_c, *low_d, *env_a;
  1182. chans = rev_chans = val = 0;
  1183. srscale = mus_srate() / 25641.0;
  1184. sample_a = sample_b = sample_c = sample_d = inrev = outrev = 0.0;
  1185. beg = mus_seconds_to_samples(start);
  1186. if (dur > 0.0)
  1187. len = beg + mus_seconds_to_samples(dur);
  1188. else
  1189. len = beg + mus_seconds_to_samples(1.0) +
  1190. mus_sound_frames(mus_file_name(rev));
  1191. chans = mus_channels(out);
  1192. rev_chans = mus_channels(rev);
  1193. env_a = mus_make_env(amp_env, amp_len / 2, output_scale, 0.0, 1.0,
  1194. dur, 0, NULL);
  1195. for (i = 0; i < 14; i++) {
  1196. int x;
  1197. x = dly_len[i];
  1198. val = (int)floor(srscale * x);
  1199. if ((val % 2) == 0)
  1200. val++;
  1201. while (!prime_p(val))
  1202. val += 2;
  1203. dly_len[i] = val;
  1204. }
  1205. i = 0;
  1206. comb1 = mus_make_comb(reverb_factor * 0.822, dly_len[i], NULL,
  1207. dly_len[i], MUS_INTERP_LINEAR);
  1208. i++;
  1209. comb2 = mus_make_comb(reverb_factor * 0.802, dly_len[i], NULL,
  1210. dly_len[i], MUS_INTERP_LINEAR);
  1211. i++;
  1212. comb3 = mus_make_comb(reverb_factor * 0.773, dly_len[i], NULL,
  1213. dly_len[i], MUS_INTERP_LINEAR);
  1214. i++;
  1215. comb4 = mus_make_comb(reverb_factor * 0.753, dly_len[i], NULL,
  1216. dly_len[i], MUS_INTERP_LINEAR);
  1217. i++;
  1218. comb5 = mus_make_comb(reverb_factor * 0.753, dly_len[i], NULL,
  1219. dly_len[i], MUS_INTERP_LINEAR);
  1220. i++;
  1221. comb6 = mus_make_comb(reverb_factor * 0.733, dly_len[i], NULL,
  1222. dly_len[i], MUS_INTERP_LINEAR);
  1223. i++;
  1224. low = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0);
  1225. low_a = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0);
  1226. low_b = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0);
  1227. low_c = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0);
  1228. low_d = mus_make_one_pole(lp_out_coeff, lp_coeff - 1.0);
  1229. allpass1 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1230. MUS_INTERP_LINEAR);
  1231. i++;
  1232. allpass2 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1233. MUS_INTERP_LINEAR);
  1234. i++;
  1235. allpass3 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1236. MUS_INTERP_LINEAR);
  1237. i += 2;
  1238. allpass4 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1239. MUS_INTERP_LINEAR);
  1240. i++;
  1241. allpass5 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1242. MUS_INTERP_LINEAR);
  1243. i++;
  1244. allpass6 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1245. MUS_INTERP_LINEAR);
  1246. i++;
  1247. allpass7 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1248. MUS_INTERP_LINEAR);
  1249. i++;
  1250. allpass8 = mus_make_all_pass(-0.7, 0.7, dly_len[i], NULL, dly_len[i],
  1251. MUS_INTERP_LINEAR);
  1252. for (i = beg; i < len; i++) {
  1253. int j;
  1254. mus_float_t ho;
  1255. for (j = 0, ho = 0.0; j < rev_chans; j++)
  1256. ho += mus_in_any(i, j, rev);
  1257. inrev = volume * mus_env(env_a) * ho;
  1258. outrev = mus_all_pass_unmodulated(allpass4,
  1259. mus_one_pole(low, mus_all_pass_unmodulated(allpass3,
  1260. mus_all_pass_unmodulated(allpass2,
  1261. mus_all_pass_unmodulated(allpass1,
  1262. mus_comb_unmodulated(comb1, inrev) +
  1263. mus_comb_unmodulated(comb2, inrev) +
  1264. mus_comb_unmodulated(comb3, inrev) +
  1265. mus_comb_unmodulated(comb4, inrev) +
  1266. mus_comb_unmodulated(comb5, inrev) +
  1267. mus_comb_unmodulated(comb6, inrev))))));
  1268. sample_a = output_scale * mus_one_pole(low_a,
  1269. mus_all_pass_unmodulated(allpass5, outrev));
  1270. sample_b = output_scale * mus_one_pole(low_b,
  1271. mus_all_pass_unmodulated(allpass6, outrev));
  1272. sample_c = output_scale * mus_one_pole(low_c,
  1273. mus_all_pass_unmodulated(allpass7, outrev));
  1274. sample_d = output_scale * mus_one_pole(low_d,
  1275. mus_all_pass_unmodulated(allpass8, outrev));
  1276. if (chans == 2)
  1277. mus_out_any(i, (sample_a + sample_d) / 2.0, 0, out);
  1278. else
  1279. mus_out_any(i, sample_a, 0, out);
  1280. if (chans == 2 || chans == 4) {
  1281. if (chans == 2)
  1282. mus_out_any(i,
  1283. (sample_b + sample_c) / 2.0, 1, out);
  1284. else
  1285. mus_out_any(i, sample_b, 1, out);
  1286. }
  1287. if (chans == 4) {
  1288. mus_out_any(i, sample_c, 2, out);
  1289. mus_out_any(i, sample_d, 3, out);
  1290. }
  1291. }
  1292. mus_free(allpass1);
  1293. mus_free(allpass2);
  1294. mus_free(allpass3);
  1295. mus_free(allpass4);
  1296. mus_free(allpass5);
  1297. mus_free(allpass6);
  1298. mus_free(allpass7);
  1299. mus_free(allpass8);
  1300. mus_free(comb1);
  1301. mus_free(comb2);
  1302. mus_free(comb3);
  1303. mus_free(comb4);
  1304. mus_free(comb5);
  1305. mus_free(comb6);
  1306. mus_free(env_a);
  1307. mus_free(low);
  1308. mus_free(low_a);
  1309. mus_free(low_b);
  1310. mus_free(low_c);
  1311. mus_free(low_d);
  1312. return (i);
  1313. }
  1314. #define FV_WARN "input must be mono or in channels must equal out channels"
  1315. mus_long_t
  1316. ins_freeverb(mus_float_t start, mus_float_t dur, mus_float_t room_decay,
  1317. mus_float_t damping, mus_float_t global, mus_float_t predelay,
  1318. mus_float_t output_gain, mus_float_t scale_room_decay,
  1319. mus_float_t offset_room_decay, mus_float_t scale_damping,
  1320. mus_float_t stereo_spread, int *combtuning, int comb_len,
  1321. int *allpasstuning, int all_len, mus_any *output_mixer,
  1322. mus_any *out, mus_any *rev)
  1323. {
  1324. mus_long_t i, beg, len;
  1325. int out_chans, in_chans;
  1326. mus_float_t srate_scale;
  1327. mus_float_t local_gain, global_gain;
  1328. mus_float_t tmp;
  1329. mus_any *out_mix = NULL, *out_buf = NULL, *f_out = NULL, *f_in = NULL;
  1330. out_chans = in_chans = 0;
  1331. srate_scale = mus_srate() / 44100.0;
  1332. local_gain = global_gain = 0.0;
  1333. beg = mus_seconds_to_samples(start);
  1334. if (dur > 0.0)
  1335. len = beg + mus_seconds_to_samples(dur);
  1336. else
  1337. len = beg + mus_seconds_to_samples(1.0) +
  1338. mus_sound_frames(mus_file_name(rev));
  1339. out_chans = mus_channels(out);
  1340. in_chans = mus_channels(rev);
  1341. if (in_chans > 1 && in_chans != out_chans)
  1342. INS_MISC_ERROR(S_freeverb, FV_WARN);
  1343. out_buf = mus_make_empty_frame(out_chans);
  1344. f_out = mus_make_empty_frame(out_chans);
  1345. f_in = mus_make_empty_frame(in_chans);
  1346. local_gain = (1.0 - global)*(1.0 - 1.0 / out_chans) + 1.0 / out_chans;
  1347. tmp = (out_chans * out_chans - out_chans);
  1348. if (tmp < 1.0)
  1349. tmp = 1.0;
  1350. global_gain = (out_chans - local_gain * out_chans) / tmp;
  1351. if (mus_mixer_p(output_mixer))
  1352. out_mix = output_mixer;
  1353. else {
  1354. out_mix = mus_make_empty_mixer(out_chans);
  1355. for (i = 0; i < out_chans; i++) {
  1356. int j;
  1357. for (j = 0; j < out_chans; j++)
  1358. mus_mixer_set(out_mix, i, j,
  1359. ((output_gain * ((i == j) ?
  1360. local_gain : global_gain)) / out_chans));
  1361. }
  1362. }
  1363. {
  1364. int j, k, size;
  1365. mus_float_t room_decay_val;
  1366. mus_any **predelays, ***allpasses, ***combs;
  1367. predelays = malloc(in_chans * sizeof(mus_any *));
  1368. if (predelays == NULL)
  1369. INS_NO_MEMORY_ERROR("ins_freeverb");
  1370. allpasses = malloc(out_chans * sizeof(mus_any **));
  1371. if (allpasses == NULL)
  1372. INS_NO_MEMORY_ERROR("ins_freeverb");
  1373. combs = malloc(out_chans * sizeof(mus_any **));
  1374. if (combs == NULL)
  1375. INS_NO_MEMORY_ERROR("ins_freeverb");
  1376. room_decay_val = room_decay * scale_room_decay +
  1377. offset_room_decay;
  1378. for (i = 0; i < out_chans; i++) {
  1379. allpasses[i] = malloc(all_len * sizeof(mus_any *));
  1380. if (allpasses[i] == NULL)
  1381. INS_NO_MEMORY_ERROR("ins_freeverb");
  1382. combs[i] = malloc(comb_len * sizeof(mus_any *));
  1383. if (combs[i] == NULL)
  1384. INS_NO_MEMORY_ERROR("ins_freeverb");
  1385. }
  1386. /* predelays */
  1387. for (i = 0; i < in_chans; i++) {
  1388. size = (int)floor(mus_srate() * predelay);
  1389. predelays[i] = mus_make_delay(size, NULL, size,
  1390. MUS_INTERP_LINEAR);
  1391. }
  1392. for (i = 0; i < out_chans; i++) {
  1393. /* comb filters */
  1394. for (j = 0; j < comb_len; j++) {
  1395. mus_float_t dmp;
  1396. dmp = scale_damping * damping;
  1397. size = (int)floor(srate_scale * combtuning[j]);
  1398. if ((i % 2) != 0)
  1399. size += (int)floor(srate_scale *
  1400. stereo_spread);
  1401. combs[i][j] = mus_make_fcomb(room_decay_val,
  1402. size, 1.0 - dmp, dmp);
  1403. }
  1404. /* allpass filters */
  1405. for (j = 0; j < all_len; j++) {
  1406. size = (int)floor(srate_scale *
  1407. allpasstuning[j]);
  1408. if ((i % 2) != 0)
  1409. size += (int)floor(srate_scale *
  1410. stereo_spread);
  1411. allpasses[i][j] = mus_make_all_pass(0.5, -1.0,
  1412. size, NULL, size, MUS_INTERP_LINEAR);
  1413. }
  1414. }
  1415. /* run loop */
  1416. for (i = beg; i < len; i++) {
  1417. f_in = mus_file_to_frame(rev, i, f_in);
  1418. if (in_chans > 1) {
  1419. for (j = 0; j < out_chans; j++) {
  1420. mus_frame_set(f_in, j,
  1421. mus_delay_unmodulated(predelays[j],
  1422. mus_frame_ref(f_in, j)));
  1423. mus_frame_set(f_out, j, 0.0);
  1424. for (k = 0; k < comb_len; k++)
  1425. mus_frame_set(f_out, j,
  1426. mus_frame_ref(f_out, j) +
  1427. mus_fcomb(combs[j][k],
  1428. mus_frame_ref(f_in, j),
  1429. 0.0));
  1430. }
  1431. } else {
  1432. mus_frame_set(f_in, 0,
  1433. mus_delay_unmodulated(predelays[0],
  1434. mus_frame_ref(f_in, 0)));
  1435. for (j = 0; j < out_chans; j++) {
  1436. mus_frame_set(f_out, j, 0.0);
  1437. for (k = 0; k < comb_len; k++)
  1438. mus_frame_set(f_out, j,
  1439. mus_frame_ref(f_out, j) +
  1440. mus_fcomb(combs[j][k],
  1441. mus_frame_ref(f_in, 0),
  1442. 0.0));
  1443. }
  1444. }
  1445. for (j = 0; j < out_chans; j++)
  1446. for (k = 0; k < all_len; k++)
  1447. mus_frame_set(f_out, j,
  1448. mus_all_pass_unmodulated(
  1449. allpasses[j][k],
  1450. mus_frame_ref(f_out, j)));
  1451. mus_frame_to_file(out, i, mus_frame_to_frame(out_mix,
  1452. f_out, out_buf));
  1453. } /* run loop */
  1454. for (i = 0; i < in_chans; i++)
  1455. mus_free(predelays[i]);
  1456. free(predelays);
  1457. for (i = 0; i < out_chans; i++) {
  1458. for (j = 0; j < comb_len; j++)
  1459. mus_free(combs[i][j]);
  1460. free(combs[i]);
  1461. for (j = 0; j < all_len; j++)
  1462. mus_free(allpasses[i][j]);
  1463. free(allpasses[i]);
  1464. }
  1465. free(combs);
  1466. free(allpasses);
  1467. } /* block */
  1468. if (!output_mixer)
  1469. mus_free(out_mix);
  1470. mus_free(out_buf);
  1471. mus_free(f_out);
  1472. mus_free(f_in);
  1473. return (i);
  1474. }
  1475. #define h_fm_violin_args "\
  1476. keyword arguments with default values:\n\
  1477. :startime 0.0\n\
  1478. :duration 1.0\n\
  1479. :frequency 440.0\n\
  1480. :amplitude 0.5\n\
  1481. :fm-index 1.0\n\
  1482. :amp-env " INS_LIST_BEG " 0 0 25 1 75 1 100 0 " INS_LIST_END "\n\
  1483. :periodic-vibrato-rate 5.0\n\
  1484. :periodic-vibrato-amplitude 0.0025\n\
  1485. :random-vibrato-rate 16.0\n\
  1486. :random-vibrato-amplitude 0.005\n\
  1487. :noise-freq 1000.0\n\
  1488. :noise-amount 0.0\n\
  1489. :ind-noise-freq 10.0\n\
  1490. :ind-noise-amount 0.0\n\
  1491. :amp-noise-freq 20.0\n\
  1492. :amp-noise-amount 0.0\n\
  1493. :gliss-env " INS_LIST_BEG " 0 0 100 0 " INS_LIST_END "\n\
  1494. :glissando-amount 0.0\n\
  1495. :fm1-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\
  1496. :fm2-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\
  1497. :fm3-env " INS_LIST_BEG " 0 1 25 0.4 75 0.6 100 0 " INS_LIST_END "\n\
  1498. :fm1-rat 1.0\n\
  1499. :fm2-rat 3.0\n\
  1500. :fm3-rat 4.0\n\
  1501. :fm1-index " INS_FALSE "\n\
  1502. :fm2-index " INS_FALSE "\n\
  1503. :fm3-index " INS_FALSE "\n\
  1504. :base 1.0\n\
  1505. :degree 0.0\n\
  1506. :distance 1.0\n\
  1507. :reverb-amount 0.01\n\
  1508. :index-type " INS_SYMBOL_PREFIX "violin (" INS_SYMBOL_PREFIX "cello or " INS_SYMBOL_PREFIX "violin)\n\
  1509. :no-waveshaping " INS_FALSE
  1510. #if HAVE_RUBY
  1511. #define H_fm_violin S_fm_violin "(*args)\n" h_fm_violin_args "\n\
  1512. require 'ws'\n\
  1513. require 'sndins'\n\
  1514. with_sound(:reverb, :jc_reverb, :reverb_data, [:volume, 0.8]) do\n\
  1515. fm_violin(0, 1, 440, 0.2, :fm_index, 1.3)\n\
  1516. end"
  1517. #elif HAVE_FORTH
  1518. #define H_fm_violin S_fm_violin " ( args -- )\n" h_fm_violin_args "\n\
  1519. require clm\n\
  1520. dl-load sndins Init_sndins\n\
  1521. 0 1 440 0.2 :fm-index 1.3 <'> fm-violin\n\
  1522. :reverb <'> jc-reverb :reverb-data #( :volume 0.8 ) with-sound"
  1523. #else /* HAVE_SCHEME */
  1524. #define H_fm_violin "(" S_fm_violin " . args)\n" h_fm_violin_args "\n\
  1525. (load \"ws.scm\")\n\
  1526. (load-extension \"libsndins\" \"Init_sndins\")\n\
  1527. (with-sound (:reverb jc-reverb :reverb-data '(:volume 0.8))\n\
  1528. (fm-violin 0 1 440 0.2 :fm-index 1.3))"
  1529. #endif
  1530. #if HAVE_FORTH
  1531. static void
  1532. #else
  1533. static XEN
  1534. #endif
  1535. c_fm_violin(XEN args)
  1536. {
  1537. #define V_LAST_KEY 33
  1538. #define XEN_V_INS_VIOLIN 1
  1539. #define XEN_V_INS_CELLO 0
  1540. mus_long_t result;
  1541. int i, vals, lst_len, mode, amp_len, gls_len;
  1542. int fm1_len, fm2_len, fm3_len;
  1543. bool index_type, no_waveshaping;
  1544. bool amp_del, gls_del, fm1_del, fm2_del, fm3_del;
  1545. mus_float_t start, dur, freq, amp, fm_index;
  1546. mus_float_t tamp_env[8] = {0.0, 0.0, 25.0, 1.0, 75.0, 1.0, 100.0, 0.0};
  1547. mus_float_t periodic_vibrato_rate, periodic_vibrato_amp;
  1548. mus_float_t random_vibrato_rate, random_vibrato_amp;
  1549. mus_float_t noise_freq, noise_amount;
  1550. mus_float_t ind_noise_freq, ind_noise_amount;
  1551. mus_float_t amp_noise_freq, amp_noise_amount;
  1552. mus_float_t tgliss_env[4] = {0.0, 0.0, 100.0, 0.0};
  1553. mus_float_t gliss_amount;
  1554. mus_float_t tfm_env[8] = {0.0, 1.0, 25.0, 0.4, 75.0, 0.6, 100.0, 0.0};
  1555. mus_float_t fm1_rat, fm2_rat, fm3_rat;
  1556. mus_float_t fm1_index, fm2_index, fm3_index, base;
  1557. mus_float_t degree, distance, reverb_amount;
  1558. mus_float_t *amp_env = NULL, *gliss_env = NULL;
  1559. mus_float_t *fm1_env = NULL, *fm2_env = NULL, *fm3_env = NULL;
  1560. mus_any *out = NULL, *rev = NULL;
  1561. XEN kargs[V_LAST_KEY * 2], keys[V_LAST_KEY];
  1562. int orig_arg[V_LAST_KEY] = {0};
  1563. lst_len = XEN_LIST_LENGTH(args);
  1564. mode = MUS_INTERP_LINEAR;
  1565. amp_len = fm1_len = fm2_len = fm3_len = 8;
  1566. gls_len = 4;
  1567. index_type = (bool)XEN_V_INS_VIOLIN;
  1568. no_waveshaping = amp_del = gls_del = false;
  1569. fm1_del = fm2_del = fm3_del = false;
  1570. start = 0.0;
  1571. dur = 1.0;
  1572. freq = 440.0;
  1573. amp = 0.5;
  1574. fm_index = 1.0;
  1575. periodic_vibrato_rate = 5.0;
  1576. periodic_vibrato_amp = 0.0025;
  1577. random_vibrato_rate = 16.0;
  1578. random_vibrato_amp = 0.005;
  1579. noise_freq = 1000.0;
  1580. noise_amount = 0.0;
  1581. ind_noise_freq = 10.0;
  1582. ind_noise_amount = 0.0;
  1583. amp_noise_freq = 20.0;
  1584. amp_noise_amount = 0.0;
  1585. gliss_amount = 0.0;
  1586. fm1_rat = 1.0;
  1587. fm2_rat = 3.0;
  1588. fm3_rat = 4.0;
  1589. fm1_index = fm2_index = fm3_index = 0.0;
  1590. base = 1.0;
  1591. degree = 0.0;
  1592. distance = 1.0;
  1593. reverb_amount = 0.01;
  1594. i = 0;
  1595. keys[i++] = allkeys[C_startime];
  1596. keys[i++] = allkeys[C_duration];
  1597. keys[i++] = allkeys[C_frequency];
  1598. keys[i++] = allkeys[C_amplitude];
  1599. keys[i++] = allkeys[C_fm_index];
  1600. keys[i++] = allkeys[C_amp_env];
  1601. keys[i++] = allkeys[C_periodic_vibrato_rate];
  1602. keys[i++] = allkeys[C_periodic_vibrato_amplitude];
  1603. keys[i++] = allkeys[C_random_vibrato_rate];
  1604. keys[i++] = allkeys[C_random_vibrato_amplitude];
  1605. keys[i++] = allkeys[C_noise_freq];
  1606. keys[i++] = allkeys[C_noise_amount];
  1607. keys[i++] = allkeys[C_ind_noise_freq];
  1608. keys[i++] = allkeys[C_ind_noise_amount];
  1609. keys[i++] = allkeys[C_amp_noise_freq];
  1610. keys[i++] = allkeys[C_amp_noise_amount];
  1611. keys[i++] = allkeys[C_gliss_env];
  1612. keys[i++] = allkeys[C_glissando_amount];
  1613. keys[i++] = allkeys[C_fm1_env];
  1614. keys[i++] = allkeys[C_fm2_env];
  1615. keys[i++] = allkeys[C_fm3_env];
  1616. keys[i++] = allkeys[C_fm1_rat];
  1617. keys[i++] = allkeys[C_fm2_rat];
  1618. keys[i++] = allkeys[C_fm3_rat];
  1619. keys[i++] = allkeys[C_fm1_index];
  1620. keys[i++] = allkeys[C_fm2_index];
  1621. keys[i++] = allkeys[C_fm3_index];
  1622. keys[i++] = allkeys[C_base];
  1623. keys[i++] = allkeys[C_degree];
  1624. keys[i++] = allkeys[C_distance];
  1625. keys[i++] = allkeys[C_reverb_amount];
  1626. keys[i++] = allkeys[C_index_type];
  1627. keys[i++] = allkeys[C_no_waveshaping];
  1628. for (i = 0; i < V_LAST_KEY * 2; i++)
  1629. kargs[i] = XEN_UNDEFINED;
  1630. for (i = 0; i < lst_len; i++)
  1631. kargs[i] = XEN_LIST_REF(args, i);
  1632. vals = mus_optkey_unscramble(S_fm_violin, V_LAST_KEY, keys, kargs,
  1633. orig_arg);
  1634. if (vals > 0) {
  1635. i = 0;
  1636. start = mus_optkey_to_float(keys[i], S_fm_violin,
  1637. orig_arg[i], start);
  1638. i++;
  1639. dur = mus_optkey_to_float(keys[i], S_fm_violin,
  1640. orig_arg[i], dur);
  1641. i++;
  1642. freq = mus_optkey_to_float(keys[i], S_fm_violin,
  1643. orig_arg[i], freq);
  1644. i++;
  1645. amp = mus_optkey_to_float(keys[i], S_fm_violin,
  1646. orig_arg[i], amp);
  1647. i++;
  1648. fm_index = mus_optkey_to_float(keys[i], S_fm_violin,
  1649. orig_arg[i], fm_index);
  1650. i++;
  1651. if (!(XEN_KEYWORD_P(keys[i]))) {
  1652. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1653. orig_arg[i], S_fm_violin, "a list");
  1654. amp_env = xen_list2array(keys[i]);
  1655. amp_len = XEN_LIST_LENGTH(keys[i]);
  1656. }
  1657. i++;
  1658. periodic_vibrato_rate = mus_optkey_to_float(keys[i],
  1659. S_fm_violin, orig_arg[i], periodic_vibrato_rate);
  1660. i++;
  1661. periodic_vibrato_amp = mus_optkey_to_float(keys[i],
  1662. S_fm_violin, orig_arg[i], periodic_vibrato_amp);
  1663. i++;
  1664. random_vibrato_rate = mus_optkey_to_float(keys[i],
  1665. S_fm_violin, orig_arg[i], random_vibrato_rate);
  1666. i++;
  1667. random_vibrato_amp = mus_optkey_to_float(keys[i],
  1668. S_fm_violin, orig_arg[i], random_vibrato_amp);
  1669. i++;
  1670. noise_freq = mus_optkey_to_float(keys[i], S_fm_violin,
  1671. orig_arg[i], noise_freq);
  1672. i++;
  1673. noise_amount = mus_optkey_to_float(keys[i], S_fm_violin,
  1674. orig_arg[i], noise_amount);
  1675. i++;
  1676. ind_noise_freq = mus_optkey_to_float(keys[i], S_fm_violin,
  1677. orig_arg[i], ind_noise_freq);
  1678. i++;
  1679. ind_noise_amount = mus_optkey_to_float(keys[i], S_fm_violin,
  1680. orig_arg[i], ind_noise_amount);
  1681. i++;
  1682. amp_noise_freq = mus_optkey_to_float(keys[i], S_fm_violin,
  1683. orig_arg[i], amp_noise_freq);
  1684. i++;
  1685. amp_noise_amount = mus_optkey_to_float(keys[i], S_fm_violin,
  1686. orig_arg[i], amp_noise_amount);
  1687. i++;
  1688. if (!(XEN_KEYWORD_P(keys[i]))) {
  1689. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1690. orig_arg[i], S_fm_violin, "a list");
  1691. gliss_env = xen_list2array(keys[i]);
  1692. gls_len = XEN_LIST_LENGTH(keys[i]);
  1693. }
  1694. i++;
  1695. gliss_amount = mus_optkey_to_float(keys[i], S_fm_violin,
  1696. orig_arg[i], gliss_amount);
  1697. i++;
  1698. if (!(XEN_KEYWORD_P(keys[i]))) {
  1699. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1700. orig_arg[i], S_fm_violin, "a list");
  1701. fm1_env = xen_list2array(keys[i]);
  1702. fm1_len = XEN_LIST_LENGTH(keys[i]);
  1703. }
  1704. i++;
  1705. if (!(XEN_KEYWORD_P(keys[i]))) {
  1706. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1707. orig_arg[i], S_fm_violin, "a list");
  1708. fm2_env = xen_list2array(keys[i]);
  1709. fm2_len = XEN_LIST_LENGTH(keys[i]);
  1710. }
  1711. i++;
  1712. if (!(XEN_KEYWORD_P(keys[i]))) {
  1713. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1714. orig_arg[i], S_fm_violin, "a list");
  1715. fm3_env = xen_list2array(keys[i]);
  1716. fm3_len = XEN_LIST_LENGTH(keys[i]);
  1717. }
  1718. i++;
  1719. fm1_rat = mus_optkey_to_float(keys[i], S_fm_violin,
  1720. orig_arg[i], fm1_rat);
  1721. i++;
  1722. fm2_rat = mus_optkey_to_float(keys[i], S_fm_violin,
  1723. orig_arg[i], fm2_rat);
  1724. i++;
  1725. fm3_rat = mus_optkey_to_float(keys[i], S_fm_violin,
  1726. orig_arg[i], fm3_rat);
  1727. i++;
  1728. if (!(XEN_KEYWORD_P(keys[i])))
  1729. if (XEN_NUMBER_P(keys[i]))
  1730. fm1_index = XEN_TO_C_DOUBLE(keys[i]);
  1731. i++;
  1732. if (!(XEN_KEYWORD_P(keys[i])))
  1733. if (XEN_NUMBER_P(keys[i]))
  1734. fm2_index = XEN_TO_C_DOUBLE(keys[i]);
  1735. i++;
  1736. if (!(XEN_KEYWORD_P(keys[i])))
  1737. if (XEN_NUMBER_P(keys[i]))
  1738. fm3_index = XEN_TO_C_DOUBLE(keys[i]);
  1739. i++;
  1740. base = mus_optkey_to_float(keys[i], S_fm_violin,
  1741. orig_arg[i], base);
  1742. i++;
  1743. degree = mus_optkey_to_float(keys[i], S_fm_violin,
  1744. orig_arg[i], degree);
  1745. i++;
  1746. distance = mus_optkey_to_float(keys[i], S_fm_violin,
  1747. orig_arg[i], distance);
  1748. i++;
  1749. reverb_amount = mus_optkey_to_float(keys[i], S_fm_violin,
  1750. orig_arg[i], reverb_amount);
  1751. i++;
  1752. if (!(XEN_KEYWORD_P(keys[i]))) {
  1753. /* cello == 0, violin == 1 */
  1754. if (XEN_SYMBOL_P(keys[i])) {
  1755. if (XEN_EQ_P(keys[i],
  1756. C_STRING_TO_XEN_SYMBOL("cello")))
  1757. index_type = XEN_V_INS_CELLO;
  1758. } else if (XEN_INTEGER_P(keys[i]))
  1759. index_type = XEN_TO_C_INT(keys[i]);
  1760. }
  1761. i++;
  1762. if (!(XEN_KEYWORD_P(keys[i]))) {
  1763. XEN_ASSERT_TYPE(XEN_BOOLEAN_P(keys[i]), keys[i],
  1764. orig_arg[i], S_fm_violin, "a bool");
  1765. no_waveshaping = XEN_TO_C_BOOLEAN(keys[i]);
  1766. }
  1767. }
  1768. if (amp_env == NULL) {
  1769. amp_env = array2array(tamp_env, 8);
  1770. amp_del = true;
  1771. }
  1772. if (gliss_env == NULL) {
  1773. gliss_env = array2array(tgliss_env, 4);
  1774. gls_del = true;
  1775. }
  1776. if (fm1_env == NULL) {
  1777. fm1_env = array2array(tfm_env, 8);
  1778. fm1_del = true;
  1779. }
  1780. if (fm2_env == NULL) {
  1781. fm2_env = array2array(tfm_env, 8);
  1782. fm2_del = true;
  1783. }
  1784. if (fm3_env == NULL) {
  1785. fm3_env = array2array(tfm_env, 8);
  1786. fm3_del = true;
  1787. }
  1788. if (!mus_output_p(out = get_global_mus_gen(INS_OUTPUT)))
  1789. INS_MISC_ERROR(S_fm_violin, "needs an output generator");
  1790. rev = get_global_mus_gen(INS_REVERB);
  1791. mode = get_global_int(INS_LOCSIG_TYPE, MUS_INTERP_LINEAR);
  1792. result = ins_fm_violin(start, dur, freq, amp, fm_index,
  1793. amp_env, amp_len, periodic_vibrato_rate, periodic_vibrato_amp,
  1794. random_vibrato_rate, random_vibrato_amp, noise_freq, noise_amount,
  1795. ind_noise_freq, ind_noise_amount, amp_noise_freq, amp_noise_amount,
  1796. gliss_env, gls_len, gliss_amount, fm1_env, fm1_len,
  1797. fm2_env, fm2_len, fm3_env, fm3_len, fm1_rat, fm2_rat, fm3_rat,
  1798. fm1_index, fm2_index, fm3_index, base, degree, distance,
  1799. reverb_amount, index_type, no_waveshaping, out, rev, mode);
  1800. if (amp_del)
  1801. free(amp_env);
  1802. if (gls_del)
  1803. free(gliss_env);
  1804. if (fm1_del)
  1805. free(fm1_env);
  1806. if (fm2_del)
  1807. free(fm2_env);
  1808. if (fm3_del)
  1809. free(fm3_env);
  1810. #if !HAVE_FORTH
  1811. return (C_TO_XEN_INT(result));
  1812. #endif
  1813. }
  1814. #define INS_REV_MSG(caller, in_chans, out_chans) \
  1815. ins_message("%s on %d in and %d out channels\n", \
  1816. caller, in_chans, out_chans)
  1817. #define INS_REV_DUR(rev) \
  1818. (mus_samples_to_seconds(mus_length(rev)) + \
  1819. get_global_float(INS_DECAY_TIME, 1.0))
  1820. #define h_jc_reverb_args "\
  1821. keyword arguments with default values:\n\
  1822. :volume 1.0\n\
  1823. :delay1 0.013\n\
  1824. :delay2 0.011\n\
  1825. :delay3 0.015\n\
  1826. :delay4 0.017\n\
  1827. :low-pass " INS_FALSE "\n\
  1828. :doubled " INS_FALSE "\n\
  1829. :amp-env " INS_FALSE
  1830. #if HAVE_RUBY
  1831. #define H_jc_reverb S_jc_reverb "(*args)\n" h_jc_reverb_args "\n\
  1832. require 'ws'\n\
  1833. require 'sndins'\n\
  1834. with_sound(:reverb, :jc_reverb, :reverb_data, [:volume, 0.8]) do\n\
  1835. fm_violin(0, 1, 440, 0.2, :fm_index, 1.3)\n\
  1836. end"
  1837. #elif HAVE_FORTH
  1838. #define H_jc_reverb S_jc_reverb " ( args -- )\n" h_jc_reverb_args "\n\
  1839. require clm\n\
  1840. dl-load sndins Init_sndins\n\
  1841. 0 1 440 0.2 :fm-index 1.3 <'> fm-violin\n\
  1842. :reverb <'> jc-reverb :reverb-data #( :volume 0.8 ) with-sound"
  1843. #else /* HAVE_SCHEME */
  1844. #define H_jc_reverb "(" S_jc_reverb " . args)\n" h_jc_reverb_args "\n\
  1845. (load-from-path \"ws.scm\")\n\
  1846. (load-extension \"libsndins\" \"Init_sndins\")\n\
  1847. (with-sound (:reverb jc-reverb :reverb-data '(:volume 0.8))\n\
  1848. (fm-violin 0 1 440 0.2 :fm-index 1.3))"
  1849. #endif
  1850. #if HAVE_FORTH
  1851. static void
  1852. #else
  1853. static XEN
  1854. #endif
  1855. c_jc_reverb(XEN args)
  1856. {
  1857. #define JC_LAST_KEY 8
  1858. mus_long_t result;
  1859. int i, vals, lst_len, amp_len;
  1860. bool low_pass, doubled;
  1861. mus_float_t volume, delay1, delay2, delay3, delay4;
  1862. mus_float_t *amp_env = NULL;
  1863. mus_any *out = NULL, *rev = NULL;
  1864. int orig_arg[JC_LAST_KEY] = {0};
  1865. XEN kargs[JC_LAST_KEY * 2], keys[JC_LAST_KEY];
  1866. amp_len = 0;
  1867. lst_len = XEN_LIST_LENGTH(args);
  1868. low_pass = doubled = false;
  1869. volume = 1.0;
  1870. delay1 = 0.013;
  1871. delay2 = 0.011;
  1872. delay3 = 0.015;
  1873. delay4 = 0.017;
  1874. i = 0;
  1875. keys[i++] = allkeys[C_low_pass];
  1876. keys[i++] = allkeys[C_volume];
  1877. keys[i++] = allkeys[C_doubled];
  1878. keys[i++] = allkeys[C_delay1];
  1879. keys[i++] = allkeys[C_delay2];
  1880. keys[i++] = allkeys[C_delay3];
  1881. keys[i++] = allkeys[C_delay4];
  1882. keys[i++] = allkeys[C_amp_env];
  1883. for (i = 0; i < JC_LAST_KEY * 2; i++)
  1884. kargs[i] = XEN_UNDEFINED;
  1885. for (i = 0; i < lst_len; i++)
  1886. kargs[i] = XEN_LIST_REF(args, i);
  1887. vals = mus_optkey_unscramble(S_jc_reverb, JC_LAST_KEY, keys, kargs,
  1888. orig_arg);
  1889. if (vals > 0) {
  1890. i = 0;
  1891. if (!(XEN_KEYWORD_P(keys[i]))) {
  1892. XEN_ASSERT_TYPE(XEN_BOOLEAN_P(keys[i]), keys[i],
  1893. orig_arg[i], S_jc_reverb, "a bool");
  1894. low_pass = XEN_TO_C_BOOLEAN(keys[i]);
  1895. }
  1896. i++;
  1897. volume = mus_optkey_to_float(keys[i], S_jc_reverb,
  1898. orig_arg[i], volume);
  1899. i++;
  1900. if (!(XEN_KEYWORD_P(keys[i]))) {
  1901. XEN_ASSERT_TYPE(XEN_BOOLEAN_P(keys[i]), keys[i],
  1902. orig_arg[i], S_jc_reverb, "a bool");
  1903. doubled = XEN_TO_C_BOOLEAN(keys[i]);
  1904. }
  1905. i++;
  1906. delay1 = mus_optkey_to_float(keys[i], S_jc_reverb,
  1907. orig_arg[i], delay1);
  1908. i++;
  1909. delay2 = mus_optkey_to_float(keys[i], S_jc_reverb,
  1910. orig_arg[i], delay2);
  1911. i++;
  1912. delay3 = mus_optkey_to_float(keys[i], S_jc_reverb,
  1913. orig_arg[i], delay3);
  1914. i++;
  1915. delay4 = mus_optkey_to_float(keys[i], S_jc_reverb,
  1916. orig_arg[i], delay4);
  1917. i++;
  1918. if (!(XEN_KEYWORD_P(keys[i]))) {
  1919. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  1920. orig_arg[i], S_jc_reverb, "a list");
  1921. amp_env = xen_list2array(keys[i]);
  1922. amp_len = XEN_LIST_LENGTH(keys[i]);
  1923. }
  1924. }
  1925. if (!mus_output_p(out = get_global_mus_gen(INS_OUTPUT)))
  1926. INS_MISC_ERROR(S_jc_reverb, "needs an output generator");
  1927. if (!mus_input_p(rev = get_global_mus_gen(INS_REVERB)))
  1928. INS_MISC_ERROR(S_jc_reverb, "needs an input generator");
  1929. if (get_global_boolean(INS_VERBOSE, false))
  1930. INS_REV_MSG(S_jc_reverb, mus_channels(rev), mus_channels(out));
  1931. result = ins_jc_reverb(0.0, INS_REV_DUR(rev), volume, low_pass,
  1932. doubled, delay1, delay2, delay3, delay4, amp_env, amp_len,
  1933. out, rev);
  1934. #if !HAVE_FORTH
  1935. return (C_TO_XEN_INT(result));
  1936. #endif
  1937. }
  1938. #define h_nrev_args "\
  1939. keyword arguments with default values:\n\
  1940. :reverb-factor 1.09\n\
  1941. :lp-coeff 0.7\n\
  1942. :lp-out-coeff 0.85\n\
  1943. :output-scale 1.0\n\
  1944. :amp-env " INS_LIST_BEG " 0 1 1 1 " INS_LIST_END "\n\
  1945. :volume 1.0"
  1946. #if HAVE_RUBY
  1947. #define H_nrev S_nrev "(*args)\n" h_nrev_args "\n\
  1948. require 'ws'\n\
  1949. require 'sndins'\n\
  1950. with_sound(:reverb, :nrev, :reverb_data, [:lp_coeff, 0.6]) do\n\
  1951. fm_violin(0, 1, 440, 0.7, :fm_index, 1.3)\n\
  1952. end"
  1953. #elif HAVE_FORTH
  1954. #define H_nrev S_nrev " ( args -- )\n" h_nrev_args "\n\
  1955. require clm\n\
  1956. dl-load sndins Init_sndins\n\
  1957. 0 1 440 0.7 :fm-index 1.3 <'> fm-violin\n\
  1958. :reverb <'> nrev :reverb-data #( :lp-coeff 0.6 ) with-sound"
  1959. #else /* HAVE_SCHEME */
  1960. #define H_nrev "(" S_nrev " . args)\n" h_nrev_args "\n\
  1961. (load \"ws.scm\")\n\
  1962. (load-extension \"libsndins\" \"Init_sndins\")\n\
  1963. (with-sound (:reverb nrev :reverb-data '(:lp-coeff 0.6))\n\
  1964. (fm-violin 0 1 440 0.7 :fm-index 1.3))"
  1965. #endif
  1966. #if HAVE_FORTH
  1967. static void
  1968. #else
  1969. static XEN
  1970. #endif
  1971. c_nrev(XEN args)
  1972. {
  1973. #define N_LAST_KEY 6
  1974. mus_long_t result;
  1975. int i, vals, lst_len, amp_len;
  1976. bool amp_del;
  1977. mus_float_t lp_coeff, lp_out_coeff;
  1978. mus_float_t output_scale, reverb_factor, volume;
  1979. mus_float_t tamp_env[4] = {0, 1, 1, 1};
  1980. mus_float_t *amp_env = NULL;
  1981. mus_any *out = NULL, *rev = NULL;
  1982. int orig_arg[N_LAST_KEY] = {0};
  1983. XEN kargs[N_LAST_KEY * 2], keys[N_LAST_KEY];
  1984. lst_len = XEN_LIST_LENGTH(args);
  1985. amp_len = 4;
  1986. amp_del = false;
  1987. lp_coeff = 0.7;
  1988. lp_out_coeff = 0.85;
  1989. output_scale = 1.0;
  1990. reverb_factor = 1.09;
  1991. volume = 1.0;
  1992. i = 0;
  1993. keys[i++] = allkeys[C_reverb_factor];
  1994. keys[i++] = allkeys[C_lp_coeff];
  1995. keys[i++] = allkeys[C_lp_out_coeff];
  1996. keys[i++] = allkeys[C_output_scale];
  1997. keys[i++] = allkeys[C_amp_env];
  1998. keys[i++] = allkeys[C_volume];
  1999. for (i = 0; i < N_LAST_KEY * 2; i++)
  2000. kargs[i] = XEN_UNDEFINED;
  2001. for (i = 0; i < lst_len; i++)
  2002. kargs[i] = XEN_LIST_REF(args, i);
  2003. vals = mus_optkey_unscramble(S_nrev, N_LAST_KEY, keys, kargs, orig_arg);
  2004. if (vals > 0) {
  2005. i = 0;
  2006. reverb_factor = mus_optkey_to_float(keys[i], S_nrev,
  2007. orig_arg[i], reverb_factor);
  2008. i++;
  2009. lp_coeff = mus_optkey_to_float(keys[i], S_nrev,
  2010. orig_arg[i], lp_coeff);
  2011. i++;
  2012. lp_out_coeff = mus_optkey_to_float(keys[i], S_nrev,
  2013. orig_arg[i], lp_out_coeff);
  2014. i++;
  2015. output_scale = mus_optkey_to_float(keys[i], S_nrev,
  2016. orig_arg[i], output_scale);
  2017. i++;
  2018. if (!(XEN_KEYWORD_P(keys[i]))) {
  2019. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  2020. orig_arg[i], S_nrev, "a list");
  2021. amp_env = xen_list2array(keys[i]);
  2022. amp_len = XEN_LIST_LENGTH(keys[i]);
  2023. }
  2024. i++;
  2025. volume = mus_optkey_to_float(keys[i], S_nrev,
  2026. orig_arg[i], volume);
  2027. }
  2028. if (amp_env == NULL) {
  2029. amp_env = array2array(tamp_env, 4);
  2030. amp_del = true;
  2031. }
  2032. if (!mus_output_p(out = get_global_mus_gen(INS_OUTPUT)))
  2033. INS_MISC_ERROR(S_nrev, "needs an output generator");
  2034. if (!mus_input_p(rev = get_global_mus_gen(INS_REVERB)))
  2035. INS_MISC_ERROR(S_nrev, "needs an input generator");
  2036. if (get_global_boolean(INS_VERBOSE, false))
  2037. INS_REV_MSG(S_nrev, mus_channels(rev), mus_channels(out));
  2038. result = ins_nrev(0.0, INS_REV_DUR(rev), reverb_factor, lp_coeff,
  2039. lp_out_coeff, output_scale, volume, amp_env, amp_len, out, rev);
  2040. if (amp_del)
  2041. free(amp_env);
  2042. #if !HAVE_FORTH
  2043. return (C_TO_XEN_INT(result));
  2044. #endif
  2045. }
  2046. #define h_freeverb_args "\
  2047. keyword arguments with default values:\n\
  2048. :room-decay 0.5\n\
  2049. :damping 0.5\n\
  2050. :global 0.3\n\
  2051. :predelay 0.03\n\
  2052. :output-gain 1.0\n\
  2053. :output-mixer " INS_FALSE "\n\
  2054. :scale-room-decay 0.28\n\
  2055. :offset-room-decay 0.7\n\
  2056. :combtuning " INS_LIST_BEG " 1116 1188 1277 1356 1422 1491 1557 1617 " INS_LIST_END "\n\
  2057. :allpasstuning " INS_LIST_BEG " 556 441 341 225 " INS_LIST_END "\n\
  2058. :scale-damping 0.4\n\
  2059. :stereo-spread 23.0"
  2060. #if HAVE_RUBY
  2061. #define H_freeverb S_freeverb "(*args)\n" h_freeverb_args "\n\
  2062. require 'ws'\n\
  2063. require 'sndins'\n\
  2064. with_sound(:reverb, :freeverb, :reverb_data, [:room_decay, 0.8]) do\n\
  2065. fm_violin(0, 1, 440, 0.7)\n\
  2066. end"
  2067. #elif HAVE_FORTH
  2068. #define H_freeverb S_freeverb " ( args -- )\n" h_freeverb_args "\n\
  2069. require clm\n\
  2070. dl-load sndins Init_sndins\n\
  2071. 0 1 440 0.7 <'> fm-violin\n\
  2072. :reverb <'> freeverb\n\
  2073. :reverb-data #( :room-decay 0.8 ) with-sound"
  2074. #else /* HAVE_SCHEME */
  2075. #define H_freeverb "(" S_freeverb " . args)\n" h_freeverb_args "\n\
  2076. (load \"ws.scm\")\n\
  2077. (load-extension \"libsndins\" \"Init_sndins\")\n\
  2078. (with-sound (:reverb freeverb :reverb-data '(:room-decay 0.8))\n\
  2079. (fm-violin 0 1 440 0.7))"
  2080. #endif
  2081. #if HAVE_FORTH
  2082. static void
  2083. #else
  2084. static XEN
  2085. #endif
  2086. c_freeverb(XEN args)
  2087. {
  2088. #define F_LAST_KEY 12
  2089. mus_long_t result;
  2090. int i, vals, lst_len, numcombs, numallpasses;
  2091. int tcombtun[8] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};
  2092. int tallpass[4] = {556, 441, 341, 225};
  2093. int *combtuning = NULL, *allpasstuning = NULL;
  2094. bool comb_del, allpass_del;
  2095. mus_float_t room_decay, global, damping;
  2096. mus_float_t predelay, output_gain, scale_room_decay;
  2097. mus_float_t offset_room_decay, scale_damping, stereo_spread;
  2098. mus_any *output_mixer = NULL, *out = NULL, *rev = NULL;
  2099. int orig_arg[F_LAST_KEY] = {0};
  2100. XEN kargs[F_LAST_KEY * 2], keys[F_LAST_KEY];
  2101. lst_len = XEN_LIST_LENGTH(args);
  2102. numcombs = 8;
  2103. numallpasses = 4;
  2104. comb_del = allpass_del = false;
  2105. room_decay = 0.5;
  2106. global = 0.3;
  2107. damping = 0.5;
  2108. predelay = 0.03;
  2109. output_gain = 1.0;
  2110. scale_room_decay = 0.28;
  2111. offset_room_decay = 0.7;
  2112. scale_damping = 0.4;
  2113. stereo_spread = 23.0;
  2114. i = 0;
  2115. keys[i++] = allkeys[C_room_decay];
  2116. keys[i++] = allkeys[C_damping];
  2117. keys[i++] = allkeys[C_global];
  2118. keys[i++] = allkeys[C_predelay];
  2119. keys[i++] = allkeys[C_output_gain];
  2120. keys[i++] = allkeys[C_output_mixer];
  2121. keys[i++] = allkeys[C_scale_room_decay];
  2122. keys[i++] = allkeys[C_offset_room_decay];
  2123. keys[i++] = allkeys[C_combtuning];
  2124. keys[i++] = allkeys[C_allpasstuning];
  2125. keys[i++] = allkeys[C_scale_damping];
  2126. keys[i++] = allkeys[C_stereo_spread];
  2127. for (i = 0; i < F_LAST_KEY * 2; i++)
  2128. kargs[i] = XEN_UNDEFINED;
  2129. for (i = 0; i < lst_len; i++)
  2130. kargs[i] = XEN_LIST_REF(args, i);
  2131. vals = mus_optkey_unscramble(S_freeverb, F_LAST_KEY, keys, kargs,
  2132. orig_arg);
  2133. if (vals > 0) {
  2134. i = 0;
  2135. room_decay = mus_optkey_to_float(keys[i], S_freeverb,
  2136. orig_arg[i], room_decay);
  2137. i++;
  2138. damping = mus_optkey_to_float(keys[i], S_freeverb,
  2139. orig_arg[i], damping);
  2140. i++;
  2141. global = mus_optkey_to_float(keys[i], S_freeverb,
  2142. orig_arg[i], global);
  2143. i++;
  2144. predelay = mus_optkey_to_float(keys[i], S_freeverb,
  2145. orig_arg[i], predelay);
  2146. i++;
  2147. output_gain = mus_optkey_to_float(keys[i], S_freeverb,
  2148. orig_arg[i], output_gain);
  2149. i++;
  2150. output_mixer = mus_optkey_to_mus_any(keys[i], S_freeverb,
  2151. orig_arg[i], output_mixer);
  2152. i++;
  2153. scale_room_decay = mus_optkey_to_float(keys[i], S_freeverb,
  2154. orig_arg[i], scale_room_decay);
  2155. i++;
  2156. offset_room_decay = mus_optkey_to_float(keys[i], S_freeverb,
  2157. orig_arg[i], offset_room_decay);
  2158. i++;
  2159. if (!(XEN_KEYWORD_P(keys[i]))) {
  2160. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  2161. orig_arg[i], S_freeverb, "a list");
  2162. combtuning = xen_list2iarray(keys[i]);
  2163. numcombs = XEN_LIST_LENGTH(keys[i]);
  2164. }
  2165. i++;
  2166. if (!(XEN_KEYWORD_P(keys[i]))) {
  2167. XEN_ASSERT_TYPE(XEN_LIST_P(keys[i]), keys[i],
  2168. orig_arg[i], S_freeverb, "a list");
  2169. allpasstuning = xen_list2iarray(keys[i]);
  2170. numallpasses = XEN_LIST_LENGTH(keys[i]);
  2171. }
  2172. i++;
  2173. scale_damping = mus_optkey_to_float(keys[i], S_freeverb,
  2174. orig_arg[i], scale_damping);
  2175. i++;
  2176. stereo_spread = mus_optkey_to_float(keys[i], S_freeverb,
  2177. orig_arg[i], stereo_spread);
  2178. }
  2179. if (!combtuning) {
  2180. combtuning = int_array2array(tcombtun, 8);
  2181. comb_del = true;
  2182. }
  2183. if (!allpasstuning) {
  2184. allpasstuning = int_array2array(tallpass, 4);
  2185. allpass_del = true;
  2186. }
  2187. if (!mus_output_p(out = get_global_mus_gen(INS_OUTPUT)))
  2188. INS_MISC_ERROR(S_freeverb, "needs an output generator");
  2189. if (!mus_input_p(rev = get_global_mus_gen(INS_REVERB)))
  2190. INS_MISC_ERROR(S_freeverb, "needs an input generator");
  2191. if (get_global_boolean(INS_VERBOSE, false))
  2192. INS_REV_MSG(S_freeverb, mus_channels(rev), mus_channels(out));
  2193. result = ins_freeverb(0.0, INS_REV_DUR(rev), room_decay, damping,
  2194. global, predelay, output_gain, scale_room_decay, offset_room_decay,
  2195. scale_damping, stereo_spread, combtuning, numcombs, allpasstuning,
  2196. numallpasses, output_mixer, out, rev);
  2197. if (comb_del)
  2198. free(combtuning);
  2199. if (allpass_del)
  2200. free(allpasstuning);
  2201. #if !HAVE_FORTH
  2202. return (C_TO_XEN_INT(result));
  2203. #endif
  2204. }
  2205. #ifdef XEN_ARGIFY_1
  2206. XEN_VARGIFY(x_make_fcomb, c_make_fcomb)
  2207. XEN_ARGIFY_2(x_fcomb, c_fcomb)
  2208. XEN_NARGIFY_1(x_fcomb_p, c_fcomb_p)
  2209. #if defined(HAVE_FORTH)
  2210. /* these are void functions */
  2211. #define x_fm_violin c_fm_violin
  2212. #define x_jc_reverb c_jc_reverb
  2213. #define x_nrev c_nrev
  2214. #define x_freeverb c_freeverb
  2215. #else
  2216. XEN_VARGIFY(x_fm_violin, c_fm_violin)
  2217. XEN_VARGIFY(x_jc_reverb, c_jc_reverb)
  2218. XEN_VARGIFY(x_nrev, c_nrev)
  2219. XEN_VARGIFY(x_freeverb, c_freeverb)
  2220. #endif
  2221. #else /* !XEN_ARGIFY_1 */
  2222. #define x_make_fcomb c_make_fcomb
  2223. #define x_fcomb c_fcomb
  2224. #define x_fcomb_p c_fcomb_p
  2225. #define x_fm_violin c_fm_violin
  2226. #define x_jc_reverb c_jc_reverb
  2227. #define x_nrev c_nrev
  2228. #define x_freeverb c_freeverb
  2229. #endif /* XEN_ARGIFY_1 */
  2230. void
  2231. Init_sndins(void)
  2232. {
  2233. init_keywords();
  2234. XEN_DEFINE_PROCEDURE(S_make_fcomb, x_make_fcomb, 0, 0, 1, H_make_fcomb);
  2235. XEN_DEFINE_PROCEDURE(S_fcomb, x_fcomb, 1, 1, 0, H_fcomb);
  2236. XEN_DEFINE_PROCEDURE(S_fcomb_p, x_fcomb_p, 1, 0, 0, H_fcomb_p);
  2237. #if HAVE_FORTH
  2238. #define XEN_DEFINE_VOID_PROC(Name, Func, Req, Opt, Rest, Help) \
  2239. fth_define_void_procedure(Name, Func, Req, Opt, Rest, Help)
  2240. XEN_DEFINE_VOID_PROC(S_fm_violin, x_fm_violin, 0, 0, 1, H_fm_violin);
  2241. XEN_DEFINE_VOID_PROC(S_jc_reverb, x_jc_reverb, 0, 0, 1, H_jc_reverb);
  2242. XEN_DEFINE_VOID_PROC(S_nrev, x_nrev, 0, 0, 1, H_nrev);
  2243. XEN_DEFINE_VOID_PROC(S_freeverb, x_freeverb, 0, 0, 1, H_freeverb);
  2244. #else
  2245. XEN_DEFINE_PROCEDURE(S_fm_violin, x_fm_violin, 0, 0, 1, H_fm_violin);
  2246. XEN_DEFINE_PROCEDURE(S_jc_reverb, x_jc_reverb, 0, 0, 1, H_jc_reverb);
  2247. XEN_DEFINE_PROCEDURE(S_nrev, x_nrev, 0, 0, 1, H_nrev);
  2248. XEN_DEFINE_PROCEDURE(S_freeverb, x_freeverb, 0, 0, 1, H_freeverb);
  2249. #endif
  2250. XEN_PROVIDE("sndins");
  2251. }
  2252. /*
  2253. * sndins.c ends here
  2254. */