tap_rotspeak.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* -*- linux-c -*-
  2. Copyright (C) 2004 Tom Szilagyi
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. $Id: tap_rotspeak.c,v 1.3 2004/02/21 17:33:36 tszilagyi Exp $
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>
  20. #include <ladspa.h>
  21. #include "tap_utils.h"
  22. /* The Unique ID of the plugin: */
  23. #define ID_STEREO 2149
  24. /* The port numbers for the plugin: */
  25. #define BASSFREQ 0
  26. #define HORNFREQ 1
  27. #define STWIDTH 2
  28. #define HRBAL 3
  29. #define LATENCY 4
  30. #define INPUT_L 5
  31. #define INPUT_R 6
  32. #define OUTPUT_L 7
  33. #define OUTPUT_R 8
  34. /* Total number of ports */
  35. #define PORTCOUNT_STEREO 9
  36. /*
  37. * This has to be bigger than 0.3f * sample_rate / (2*PI) for any sample rate.
  38. * At 192 kHz 9168 is needed so this should be enough.
  39. */
  40. #define PM_DEPTH 9200
  41. /* maximum phase mod freq */
  42. #define PM_FREQ 30.0f
  43. /* splitting input signals into low and high freq components */
  44. #define SPLIT_FREQ 1000.0f
  45. #define SPLIT_BW 1.0f
  46. /* approx. sound velocity in air [m/s] */
  47. #define C_AIR 340.0f
  48. /* coefficient between rotating frequency and pitch mod depth (aka. Doppler effect) */
  49. #define FREQ_PITCH 1.6f
  50. /* cosine table for fast computations */
  51. LADSPA_Data cos_table[1024];
  52. /* The structure used to hold port connection information and state */
  53. typedef struct {
  54. LADSPA_Data * hornfreq;
  55. LADSPA_Data * bassfreq;
  56. LADSPA_Data * stwidth;
  57. LADSPA_Data * hrbal;
  58. LADSPA_Data * latency;
  59. LADSPA_Data * input_L;
  60. LADSPA_Data * input_R;
  61. LADSPA_Data * output_L;
  62. LADSPA_Data * output_R;
  63. LADSPA_Data * ringbuffer_h_L;
  64. unsigned long buflen_h_L;
  65. unsigned long pos_h_L;
  66. LADSPA_Data * ringbuffer_h_R;
  67. unsigned long buflen_h_R;
  68. unsigned long pos_h_R;
  69. LADSPA_Data * ringbuffer_b_L;
  70. unsigned long buflen_b_L;
  71. unsigned long pos_b_L;
  72. LADSPA_Data * ringbuffer_b_R;
  73. unsigned long buflen_b_R;
  74. unsigned long pos_b_R;
  75. biquad * eq_filter_L;
  76. biquad * lp_filter_L;
  77. biquad * hp_filter_L;
  78. biquad * eq_filter_R;
  79. biquad * lp_filter_R;
  80. biquad * hp_filter_R;
  81. unsigned long sample_rate;
  82. LADSPA_Data phase_h;
  83. LADSPA_Data phase_b;
  84. LADSPA_Data run_adding_gain;
  85. } RotSpkr;
  86. void cleanup_RotSpkr(LADSPA_Handle Instance);
  87. /* Construct a new plugin instance. */
  88. LADSPA_Handle
  89. instantiate_RotSpkr(const LADSPA_Descriptor * Descriptor,
  90. unsigned long sample_rate) {
  91. LADSPA_Handle * ptr;
  92. if ((ptr = calloc(1, sizeof(RotSpkr))) != NULL) {
  93. RotSpkr* rotSpeak = (RotSpkr*)ptr;
  94. rotSpeak->sample_rate = sample_rate;
  95. rotSpeak->run_adding_gain = 1.0;
  96. if ((rotSpeak->ringbuffer_h_L =
  97. calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
  98. {
  99. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  100. return NULL;
  101. }
  102. if ((rotSpeak->ringbuffer_h_R =
  103. calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
  104. {
  105. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  106. return NULL;
  107. }
  108. rotSpeak->buflen_h_L = ceil(0.3f * sample_rate / M_PI);
  109. rotSpeak->buflen_h_R = ceil(0.3f * sample_rate / M_PI);
  110. rotSpeak->pos_h_L = 0;
  111. rotSpeak->pos_h_R = 0;
  112. if ((rotSpeak->ringbuffer_b_L =
  113. calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
  114. {
  115. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  116. return NULL;
  117. }
  118. if ((rotSpeak->ringbuffer_b_R =
  119. calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
  120. {
  121. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  122. return NULL;
  123. }
  124. rotSpeak->buflen_b_L = ceil(0.3f * sample_rate / M_PI);
  125. rotSpeak->buflen_b_R = ceil(0.3f * sample_rate / M_PI);
  126. rotSpeak->pos_b_L = 0;
  127. rotSpeak->pos_b_R = 0;
  128. if ((rotSpeak->eq_filter_L = calloc(1, sizeof(biquad))) == NULL)
  129. {
  130. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  131. return NULL;
  132. }
  133. if ((rotSpeak->lp_filter_L = calloc(1, sizeof(biquad))) == NULL)
  134. {
  135. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  136. return NULL;
  137. }
  138. if ((rotSpeak->hp_filter_L = calloc(1, sizeof(biquad))) == NULL)
  139. {
  140. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  141. return NULL;
  142. }
  143. if ((rotSpeak->eq_filter_R = calloc(1, sizeof(biquad))) == NULL)
  144. {
  145. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  146. return NULL;
  147. }
  148. if ((rotSpeak->lp_filter_R = calloc(1, sizeof(biquad))) == NULL)
  149. {
  150. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  151. return NULL;
  152. }
  153. if ((rotSpeak->hp_filter_R = calloc(1, sizeof(biquad))) == NULL)
  154. {
  155. cleanup_RotSpkr((LADSPA_Handle)rotSpeak);
  156. return NULL;
  157. }
  158. return ptr;
  159. }
  160. return NULL;
  161. }
  162. void
  163. activate_RotSpkr(LADSPA_Handle Instance) {
  164. int i;
  165. RotSpkr * ptr;
  166. ptr = (RotSpkr *)Instance;
  167. for (i = 0; i < 2 * PM_DEPTH; i++) {
  168. ptr->ringbuffer_h_L[i] = 0.0f;
  169. ptr->ringbuffer_h_R[i] = 0.0f;
  170. ptr->ringbuffer_b_L[i] = 0.0f;
  171. ptr->ringbuffer_b_R[i] = 0.0f;
  172. }
  173. ptr->phase_h = 0.0f;
  174. ptr->phase_b = 0.0f;
  175. biquad_init(ptr->eq_filter_L);
  176. biquad_init(ptr->lp_filter_L);
  177. biquad_init(ptr->hp_filter_L);
  178. biquad_init(ptr->eq_filter_R);
  179. biquad_init(ptr->lp_filter_R);
  180. biquad_init(ptr->hp_filter_R);
  181. eq_set_params(ptr->eq_filter_L, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
  182. eq_set_params(ptr->eq_filter_R, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
  183. lp_set_params(ptr->lp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
  184. lp_set_params(ptr->lp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
  185. hp_set_params(ptr->hp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
  186. hp_set_params(ptr->hp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
  187. }
  188. /* Connect a port to a data location. */
  189. void
  190. connect_port_RotSpkr(LADSPA_Handle Instance,
  191. unsigned long Port,
  192. LADSPA_Data * DataLocation) {
  193. RotSpkr * ptr;
  194. ptr = (RotSpkr *)Instance;
  195. switch (Port) {
  196. case HORNFREQ:
  197. ptr->hornfreq = DataLocation;
  198. break;
  199. case BASSFREQ:
  200. ptr->bassfreq = DataLocation;
  201. break;
  202. case STWIDTH:
  203. ptr->stwidth = DataLocation;
  204. break;
  205. case HRBAL:
  206. ptr->hrbal = DataLocation;
  207. break;
  208. case LATENCY:
  209. ptr->latency = DataLocation;
  210. *(ptr->latency) = ptr->buflen_h_L / 2; /* IS THIS LEGAL? YES, ONLY IF DataLocation points to valid memory location on stack/heap*/
  211. break;
  212. case INPUT_L:
  213. ptr->input_L = DataLocation;
  214. break;
  215. case INPUT_R:
  216. ptr->input_R = DataLocation;
  217. break;
  218. case OUTPUT_L:
  219. ptr->output_L = DataLocation;
  220. break;
  221. case OUTPUT_R:
  222. ptr->output_R = DataLocation;
  223. break;
  224. }
  225. }
  226. void
  227. run_RotSpkr(LADSPA_Handle Instance,
  228. unsigned long SampleCount) {
  229. RotSpkr * ptr = (RotSpkr *)Instance;
  230. LADSPA_Data * input_L = ptr->input_L;
  231. LADSPA_Data * input_R = ptr->input_R;
  232. LADSPA_Data * output_L = ptr->output_L;
  233. LADSPA_Data * output_R = ptr->output_R;
  234. LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
  235. LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
  236. LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
  237. LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
  238. LADSPA_Data pmdepth_h =
  239. LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
  240. / 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
  241. LADSPA_Data pmdepth_b =
  242. LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
  243. / 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
  244. unsigned long sample_index;
  245. LADSPA_Data in_L = 0.0f, in_R = 0.0f;
  246. LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
  247. LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
  248. LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
  249. LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
  250. LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
  251. LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
  252. LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
  253. LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
  254. LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
  255. LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
  256. LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
  257. LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
  258. LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
  259. for (sample_index = 0; sample_index < SampleCount; sample_index++) {
  260. in_L = *(input_L++);
  261. in_R = *(input_R++);
  262. in_L = biquad_run(ptr->eq_filter_L, in_L);
  263. in_R = biquad_run(ptr->eq_filter_R, in_R);
  264. lo_L = biquad_run(ptr->lp_filter_L, in_L);
  265. lo_R = biquad_run(ptr->lp_filter_R, in_R);
  266. hi_L = biquad_run(ptr->hp_filter_L, in_L);
  267. hi_R = biquad_run(ptr->hp_filter_R, in_R);
  268. phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
  269. while (phase_h_L >= 1024.0f)
  270. phase_h_L -= 1024.0f;
  271. phase_pm_h_L = phase_h_L + 256.0f;
  272. while (phase_pm_h_L >= 1024.0f)
  273. phase_pm_h_L -= 1024.0f;
  274. phase_h_R = phase_h_L + 512.0f;
  275. while (phase_h_R >= 1024.0f)
  276. phase_h_R -= 1024.0f;
  277. phase_pm_h_R = phase_h_R + 256.0f;
  278. while (phase_pm_h_R >= 1024.0f)
  279. phase_pm_h_R -= 1024.0f;
  280. phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
  281. while (phase_b_L >= 1024.0f)
  282. phase_b_L -= 1024.0f;
  283. phase_pm_b_L = phase_b_L + 256.0f;
  284. while (phase_pm_b_L >= 1024.0f)
  285. phase_pm_b_L -= 1024.0f;
  286. phase_b_R = phase_b_L + 512.0f;
  287. while (phase_b_R >= 1024.0f)
  288. phase_b_R -= 1024.0f;
  289. phase_pm_b_R = phase_b_R + 256.0f;
  290. while (phase_pm_b_R >= 1024.0f)
  291. phase_pm_b_R -= 1024.0f;
  292. push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
  293. push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
  294. push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
  295. push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
  296. fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
  297. n_h_L = floorf(fpos_h_L);
  298. rem_h_L = fpos_h_L - n_h_L;
  299. sa_h_L = read_buffer(ptr->ringbuffer_h_L,
  300. ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
  301. sb_h_L = read_buffer(ptr->ringbuffer_h_L,
  302. ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
  303. pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
  304. fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
  305. n_h_R = floorf(fpos_h_R);
  306. rem_h_R = fpos_h_R - n_h_R;
  307. sa_h_R = read_buffer(ptr->ringbuffer_h_R,
  308. ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
  309. sb_h_R = read_buffer(ptr->ringbuffer_h_R,
  310. ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
  311. pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
  312. fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
  313. n_b_L = floorf(fpos_b_L);
  314. rem_b_L = fpos_b_L - n_b_L;
  315. sa_b_L = read_buffer(ptr->ringbuffer_b_L,
  316. ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
  317. sb_b_L = read_buffer(ptr->ringbuffer_b_L,
  318. ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
  319. pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
  320. fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
  321. n_b_R = floorf(fpos_b_R);
  322. rem_b_R = fpos_b_R - n_b_R;
  323. sa_b_R = read_buffer(ptr->ringbuffer_b_R,
  324. ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
  325. sb_b_R = read_buffer(ptr->ringbuffer_b_R,
  326. ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
  327. pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
  328. *(output_L++) =
  329. hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
  330. cos_table[(unsigned long) phase_h_L]) +
  331. (1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
  332. cos_table[(unsigned long) phase_b_L]);
  333. *(output_R++) =
  334. hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
  335. cos_table[(unsigned long) phase_h_R]) +
  336. (1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
  337. cos_table[(unsigned long) phase_b_R]);
  338. }
  339. ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
  340. while (ptr->phase_h >= 1024.0f)
  341. ptr->phase_h -= 1024.0f;
  342. ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
  343. while (ptr->phase_b >= 1024.0f)
  344. ptr->phase_b -= 1024.0f;
  345. *(ptr->latency) = ptr->buflen_h_L / 2;
  346. }
  347. void
  348. set_run_adding_gain_RotSpkr(LADSPA_Handle Instance, LADSPA_Data gain) {
  349. RotSpkr * ptr = (RotSpkr *)Instance;
  350. ptr->run_adding_gain = gain;
  351. }
  352. void
  353. run_adding_RotSpkr(LADSPA_Handle Instance,
  354. unsigned long SampleCount) {
  355. RotSpkr * ptr = (RotSpkr *)Instance;
  356. LADSPA_Data * input_L = ptr->input_L;
  357. LADSPA_Data * input_R = ptr->input_R;
  358. LADSPA_Data * output_L = ptr->output_L;
  359. LADSPA_Data * output_R = ptr->output_R;
  360. LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
  361. LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
  362. LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
  363. LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
  364. LADSPA_Data pmdepth_h =
  365. LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
  366. / 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
  367. LADSPA_Data pmdepth_b =
  368. LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
  369. / 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
  370. unsigned long sample_index;
  371. LADSPA_Data in_L = 0.0f, in_R = 0.0f;
  372. LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
  373. LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
  374. LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
  375. LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
  376. LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
  377. LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
  378. LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
  379. LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
  380. LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
  381. LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
  382. LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
  383. LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
  384. LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
  385. for (sample_index = 0; sample_index < SampleCount; sample_index++) {
  386. in_L = *(input_L++);
  387. in_R = *(input_R++);
  388. in_L = biquad_run(ptr->eq_filter_L, in_L);
  389. in_R = biquad_run(ptr->eq_filter_R, in_R);
  390. lo_L = biquad_run(ptr->lp_filter_L, in_L);
  391. lo_R = biquad_run(ptr->lp_filter_R, in_R);
  392. hi_L = biquad_run(ptr->hp_filter_L, in_L);
  393. hi_R = biquad_run(ptr->hp_filter_R, in_R);
  394. phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
  395. while (phase_h_L >= 1024.0f)
  396. phase_h_L -= 1024.0f;
  397. phase_pm_h_L = phase_h_L + 256.0f;
  398. while (phase_pm_h_L >= 1024.0f)
  399. phase_pm_h_L -= 1024.0f;
  400. phase_h_R = phase_h_L + 512.0f;
  401. while (phase_h_R >= 1024.0f)
  402. phase_h_R -= 1024.0f;
  403. phase_pm_h_R = phase_h_R + 256.0f;
  404. while (phase_pm_h_R >= 1024.0f)
  405. phase_pm_h_R -= 1024.0f;
  406. phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
  407. while (phase_b_L >= 1024.0f)
  408. phase_b_L -= 1024.0f;
  409. phase_pm_b_L = phase_b_L + 256.0f;
  410. while (phase_pm_b_L >= 1024.0f)
  411. phase_pm_b_L -= 1024.0f;
  412. phase_b_R = phase_b_L + 512.0f;
  413. while (phase_b_R >= 1024.0f)
  414. phase_b_R -= 1024.0f;
  415. phase_pm_b_R = phase_b_R + 256.0f;
  416. while (phase_pm_b_R >= 1024.0f)
  417. phase_pm_b_R -= 1024.0f;
  418. push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
  419. push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
  420. push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
  421. push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
  422. fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
  423. n_h_L = floorf(fpos_h_L);
  424. rem_h_L = fpos_h_L - n_h_L;
  425. sa_h_L = read_buffer(ptr->ringbuffer_h_L,
  426. ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
  427. sb_h_L = read_buffer(ptr->ringbuffer_h_L,
  428. ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
  429. pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
  430. fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
  431. n_h_R = floorf(fpos_h_R);
  432. rem_h_R = fpos_h_R - n_h_R;
  433. sa_h_R = read_buffer(ptr->ringbuffer_h_R,
  434. ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
  435. sb_h_R = read_buffer(ptr->ringbuffer_h_R,
  436. ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
  437. pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
  438. fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
  439. n_b_L = floorf(fpos_b_L);
  440. rem_b_L = fpos_b_L - n_b_L;
  441. sa_b_L = read_buffer(ptr->ringbuffer_b_L,
  442. ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
  443. sb_b_L = read_buffer(ptr->ringbuffer_b_L,
  444. ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
  445. pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
  446. fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
  447. n_b_R = floorf(fpos_b_R);
  448. rem_b_R = fpos_b_R - n_b_R;
  449. sa_b_R = read_buffer(ptr->ringbuffer_b_R,
  450. ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
  451. sb_b_R = read_buffer(ptr->ringbuffer_b_R,
  452. ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
  453. pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
  454. *(output_L++) += ptr->run_adding_gain *
  455. hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
  456. cos_table[(unsigned long) phase_h_L]) +
  457. (1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
  458. cos_table[(unsigned long) phase_b_L]);
  459. *(output_R++) += ptr->run_adding_gain *
  460. hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
  461. cos_table[(unsigned long) phase_h_R]) +
  462. (1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
  463. cos_table[(unsigned long) phase_b_R]);
  464. }
  465. ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
  466. while (ptr->phase_h >= 1024.0f)
  467. ptr->phase_h -= 1024.0f;
  468. ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
  469. while (ptr->phase_b >= 1024.0f)
  470. ptr->phase_b -= 1024.0f;
  471. *(ptr->latency) = ptr->buflen_h_L / 2;
  472. }
  473. /*
  474. Throw away an RotSpkr effect instance.
  475. This function should be called only when RotSpkr was allocated with calloc.
  476. */
  477. void
  478. cleanup_RotSpkr(LADSPA_Handle Instance) {
  479. RotSpkr * ptr = (RotSpkr *)Instance;
  480. if (!ptr)
  481. return;
  482. if (ptr->ringbuffer_h_L)
  483. free(ptr->ringbuffer_h_L);
  484. if (ptr->ringbuffer_h_R)
  485. free(ptr->ringbuffer_h_R);
  486. if (ptr->ringbuffer_b_L)
  487. free(ptr->ringbuffer_b_L);
  488. if (ptr->ringbuffer_b_R)
  489. free(ptr->ringbuffer_b_R);
  490. if (ptr->eq_filter_L)
  491. free(ptr->eq_filter_L);
  492. if (ptr->eq_filter_R)
  493. free(ptr->eq_filter_R);
  494. if (ptr->lp_filter_L)
  495. free(ptr->lp_filter_L);
  496. if (ptr->lp_filter_R)
  497. free(ptr->lp_filter_R);
  498. if (ptr->hp_filter_L)
  499. free(ptr->hp_filter_L);
  500. if (ptr->hp_filter_R)
  501. free(ptr->hp_filter_R);
  502. if (Instance)
  503. free(Instance);
  504. }
  505. LADSPA_Descriptor * stereo_descriptor = NULL;
  506. /* __attribute__((constructor)) tap_init() is called automatically when the plugin library is first
  507. loaded. */
  508. void
  509. __attribute__((constructor)) tap_init() {
  510. int i;
  511. char ** port_names;
  512. LADSPA_PortDescriptor * port_descriptors;
  513. LADSPA_PortRangeHint * port_range_hints;
  514. if ((stereo_descriptor =
  515. (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
  516. exit(1);
  517. for (i = 0; i < 1024; i++)
  518. cos_table[i] = cosf(i * M_PI / 512.0f);
  519. stereo_descriptor->UniqueID = ID_STEREO;
  520. stereo_descriptor->Label = strdup("tap_rotspeak");
  521. stereo_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
  522. stereo_descriptor->Name = strdup("TAP Rotary Speaker");
  523. stereo_descriptor->Maker = strdup("Tom Szilagyi");
  524. stereo_descriptor->Copyright = strdup("GPL");
  525. stereo_descriptor->PortCount = PORTCOUNT_STEREO;
  526. if ((port_descriptors =
  527. (LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
  528. exit(1);
  529. stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
  530. port_descriptors[HORNFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  531. port_descriptors[BASSFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  532. port_descriptors[STWIDTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  533. port_descriptors[HRBAL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  534. port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
  535. port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
  536. port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
  537. port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
  538. port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
  539. if ((port_names =
  540. (char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
  541. exit(1);
  542. stereo_descriptor->PortNames = (const char **)port_names;
  543. port_names[HORNFREQ] = strdup("Horn Frequency [Hz]");
  544. port_names[BASSFREQ] = strdup("Rotor Frequency [Hz]");
  545. port_names[STWIDTH] = strdup("Mic Distance [%]");
  546. port_names[HRBAL] = strdup("Rotor/Horn Mix");
  547. port_names[LATENCY] = strdup("latency");
  548. port_names[INPUT_L] = strdup("Input L");
  549. port_names[INPUT_R] = strdup("Input R");
  550. port_names[OUTPUT_L] = strdup("Output L");
  551. port_names[OUTPUT_R] = strdup("Output R");
  552. if ((port_range_hints =
  553. ((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
  554. exit(1);
  555. stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
  556. port_range_hints[HORNFREQ].HintDescriptor =
  557. (LADSPA_HINT_BOUNDED_BELOW |
  558. LADSPA_HINT_BOUNDED_ABOVE |
  559. LADSPA_HINT_DEFAULT_0);
  560. port_range_hints[BASSFREQ].HintDescriptor =
  561. (LADSPA_HINT_BOUNDED_BELOW |
  562. LADSPA_HINT_BOUNDED_ABOVE |
  563. LADSPA_HINT_DEFAULT_0);
  564. port_range_hints[STWIDTH].HintDescriptor =
  565. (LADSPA_HINT_BOUNDED_BELOW |
  566. LADSPA_HINT_BOUNDED_ABOVE |
  567. LADSPA_HINT_DEFAULT_LOW);
  568. port_range_hints[HRBAL].HintDescriptor =
  569. (LADSPA_HINT_BOUNDED_BELOW |
  570. LADSPA_HINT_BOUNDED_ABOVE |
  571. LADSPA_HINT_DEFAULT_MIDDLE);
  572. port_range_hints[LATENCY].HintDescriptor =
  573. (LADSPA_HINT_BOUNDED_BELOW |
  574. LADSPA_HINT_BOUNDED_ABOVE |
  575. LADSPA_HINT_DEFAULT_MAXIMUM);
  576. port_range_hints[HORNFREQ].LowerBound = 0;
  577. port_range_hints[HORNFREQ].UpperBound = PM_FREQ;
  578. port_range_hints[BASSFREQ].LowerBound = 0;
  579. port_range_hints[BASSFREQ].UpperBound = PM_FREQ;
  580. port_range_hints[STWIDTH].LowerBound = 0;
  581. port_range_hints[STWIDTH].UpperBound = 100.0f;
  582. port_range_hints[HRBAL].LowerBound = 0;
  583. port_range_hints[HRBAL].UpperBound = 1.0f;
  584. port_range_hints[LATENCY].LowerBound = 0;
  585. port_range_hints[LATENCY].UpperBound = PM_DEPTH;
  586. port_range_hints[INPUT_L].HintDescriptor = 0;
  587. port_range_hints[INPUT_R].HintDescriptor = 0;
  588. port_range_hints[OUTPUT_L].HintDescriptor = 0;
  589. port_range_hints[OUTPUT_R].HintDescriptor = 0;
  590. stereo_descriptor->instantiate = instantiate_RotSpkr;
  591. stereo_descriptor->connect_port = connect_port_RotSpkr;
  592. stereo_descriptor->activate = activate_RotSpkr;
  593. stereo_descriptor->run = run_RotSpkr;
  594. stereo_descriptor->run_adding = run_adding_RotSpkr;
  595. stereo_descriptor->set_run_adding_gain = set_run_adding_gain_RotSpkr;
  596. stereo_descriptor->deactivate = NULL;
  597. stereo_descriptor->cleanup = cleanup_RotSpkr;
  598. }
  599. void
  600. delete_descriptor(LADSPA_Descriptor * descriptor) {
  601. unsigned long index;
  602. if (descriptor) {
  603. free((char *)descriptor->Label);
  604. free((char *)descriptor->Name);
  605. free((char *)descriptor->Maker);
  606. free((char *)descriptor->Copyright);
  607. free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
  608. for (index = 0; index < descriptor->PortCount; index++)
  609. free((char *)(descriptor->PortNames[index]));
  610. free((char **)descriptor->PortNames);
  611. free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
  612. free(descriptor);
  613. }
  614. }
  615. /* __attribute__((destructor)) tap_fini() is called automatically when the library is unloaded. */
  616. void
  617. __attribute__((destructor)) tap_fini() {
  618. delete_descriptor(stereo_descriptor);
  619. }
  620. /* Return a descriptor of the requested plugin type. */
  621. const LADSPA_Descriptor *
  622. ladspa_descriptor(unsigned long Index) {
  623. switch (Index) {
  624. case 0:
  625. return stereo_descriptor;
  626. default:
  627. return NULL;
  628. }
  629. }