aRts audio server
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.

gslosctable.c 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /* GSL - Generic Sound Layer
  2. * Copyright (C) 2001-2002 Tim Janik
  3. *
  4. * This library is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Library General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. * Boston, MA 02110-1301, USA.
  18. */
  19. #include "gslosctable.h"
  20. #include <string.h>
  21. #include "gbsearcharray.h"
  22. #include "gslcommon.h"
  23. #include "gslmath.h"
  24. #include "gslfft.h"
  25. #define OSC_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_OSC, G_STRLOC)
  26. #define OSC_FREQ_EPSILON (1e-3) /* range within which frequencies are "equal" */
  27. /* compare mfreqs against each other, use an arbitrary sample rate
  28. * for which OSC_FREQ_EPSILON makes sense
  29. */
  30. #define CACHE_MATCH_FREQ(usr_mfreq, cache_mfreq) \
  31. (fabs ((cache_mfreq) * 44107 - (usr_mfreq) * 44107) < OSC_FREQ_EPSILON)
  32. /* --- structures --- */
  33. typedef struct
  34. {
  35. /* main key (osc and cache tables) */
  36. gfloat mfreq; /* [0..0.5], mix_freq relative */
  37. /* secondary key (cache tables) */
  38. GslOscWaveForm wave_form;
  39. guint8 *filter_func; /* just here for key indexing */
  40. /* data */
  41. guint ref_count;
  42. guint min_pos, max_pos; /* pulse extension */
  43. guint n_values;
  44. const gfloat values[1]; /* flexible array */
  45. } OscTableEntry;
  46. /* --- prototypes --- */
  47. static gint cache_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
  48. gconstpointer bsearch_node2);
  49. static gint osc_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
  50. gconstpointer bsearch_node2);
  51. static void osc_wave_extrema_pos (guint n_values,
  52. const gfloat *values,
  53. guint *minp_p,
  54. guint *maxp_p);
  55. void gsl_osc_cache_debug_dump (void);
  56. /* --- variables --- */
  57. static GBSearchArray *cache_entries = NULL;
  58. static const GBSearchConfig cache_taconfig = {
  59. sizeof (OscTableEntry*),
  60. cache_table_entry_locs_cmp,
  61. 0
  62. };
  63. static const GBSearchConfig osc_taconfig = {
  64. sizeof (OscTableEntry*),
  65. osc_table_entry_locs_cmp,
  66. 0
  67. };
  68. /* --- functions --- */
  69. static gint
  70. cache_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
  71. gconstpointer bsearch_node2)
  72. {
  73. const OscTableEntry * const *ep1 = bsearch_node1;
  74. const OscTableEntry * const *ep2 = bsearch_node2;
  75. const OscTableEntry *e1 = *ep1;
  76. const OscTableEntry *e2 = *ep2;
  77. if (e1->wave_form == e2->wave_form)
  78. {
  79. if (e1->filter_func == e2->filter_func)
  80. return G_BSEARCH_ARRAY_CMP (e1->mfreq, e2->mfreq);
  81. else
  82. return e1->filter_func > e2->filter_func ? 1 : -1;
  83. }
  84. else
  85. return e1->wave_form > e2->wave_form ? 1 : -1;
  86. }
  87. static gint
  88. osc_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
  89. gconstpointer bsearch_node2)
  90. {
  91. const OscTableEntry * const *ep1 = bsearch_node1;
  92. const OscTableEntry * const *ep2 = bsearch_node2;
  93. const OscTableEntry *e1 = *ep1;
  94. const OscTableEntry *e2 = *ep2;
  95. return G_BSEARCH_ARRAY_CMP (e1->mfreq, e2->mfreq);
  96. }
  97. static OscTableEntry*
  98. cache_table_entry_lookup_best (GslOscWaveForm wave_form,
  99. guint8* filter_func,
  100. gfloat mfreq)
  101. {
  102. OscTableEntry key, *k = &key, **ep1 = NULL, **ep2, **ep3 = NULL;
  103. key.mfreq = mfreq;
  104. key.wave_form = wave_form;
  105. key.filter_func = filter_func;
  106. /* get exact match or a match which is one off into either direction */
  107. ep2 = g_bsearch_array_lookup_sibling (cache_entries, &cache_taconfig, &k);
  108. if (ep2)
  109. {
  110. guint i = g_bsearch_array_get_index (cache_entries, &cache_taconfig, ep2);
  111. /* get siblings */
  112. if (i > 0)
  113. ep1 = g_bsearch_array_get_nth (cache_entries, &cache_taconfig, i - 1);
  114. if (i + 1 < g_bsearch_array_get_n_nodes (cache_entries))
  115. ep3 = g_bsearch_array_get_nth (cache_entries, &cache_taconfig, i + 1);
  116. /* get rid of invalid matches, i.e. ones with:
  117. * - a different wave
  118. * - a different filter
  119. * - a filter wider than required
  120. */
  121. if (ep1 && ((*ep1)->wave_form != wave_form ||
  122. (*ep1)->filter_func != filter_func ||
  123. (*ep1)->mfreq < mfreq))
  124. ep1 = NULL;
  125. if (ep3 && ((*ep3)->wave_form != wave_form ||
  126. (*ep3)->filter_func != filter_func ||
  127. (*ep3)->mfreq < mfreq))
  128. ep3 = NULL;
  129. if ((*ep2)->wave_form != wave_form ||
  130. (*ep2)->filter_func != filter_func ||
  131. (*ep2)->mfreq < mfreq)
  132. {
  133. /* collapse siblings, so that, if we have valid matches, ep2 is amongst them */
  134. if (ep1)
  135. {
  136. ep2 = ep1;
  137. ep1 = NULL;
  138. }
  139. else if (ep3)
  140. {
  141. ep2 = ep3;
  142. ep3 = NULL;
  143. }
  144. else
  145. ep2 = NULL; /* no valid match at all */
  146. }
  147. }
  148. /* now figure best out of valid siblings */
  149. if (ep2)
  150. {
  151. if (ep1 && fabs ((*ep1)->mfreq - mfreq) < fabs ((*ep2)->mfreq - mfreq))
  152. ep2 = ep1;
  153. if (ep3 && fabs ((*ep3)->mfreq - mfreq) < fabs ((*ep2)->mfreq - mfreq))
  154. ep2 = ep3;
  155. }
  156. return ep2 ? *ep2 : NULL;
  157. }
  158. static OscTableEntry*
  159. osc_table_entry_lookup_best (const GslOscTable *table,
  160. gfloat mfreq,
  161. gfloat *min_mfreq)
  162. {
  163. OscTableEntry key, *k = &key, **ep;
  164. guint i;
  165. /* get exact match or a match which is one off into either direction */
  166. key.mfreq = mfreq;
  167. ep = g_bsearch_array_lookup_sibling (table->entry_array, &osc_taconfig, &k);
  168. if_reject (!ep)
  169. return NULL; /* ugh, bad */
  170. if (mfreq > (*ep)->mfreq) /* need better filter */
  171. {
  172. i = g_bsearch_array_get_index (table->entry_array, &osc_taconfig, ep);
  173. if (i + 1 < g_bsearch_array_get_n_nodes (table->entry_array))
  174. ep = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, i + 1);
  175. else /* bad, might cause aliasing */
  176. OSC_DEBUG ("lookup mismatch, aliasing possible: want_freq=%f got_freq=%f",
  177. mfreq * table->mix_freq, (*ep)->mfreq * table->mix_freq);
  178. }
  179. if (min_mfreq)
  180. {
  181. /* fetch mfreq from previous */
  182. i = g_bsearch_array_get_index (table->entry_array, &osc_taconfig, ep);
  183. if (i > 0)
  184. {
  185. OscTableEntry **tp = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, i - 1);
  186. *min_mfreq = (*tp)->mfreq;
  187. }
  188. else
  189. *min_mfreq = 0;
  190. }
  191. return *ep;
  192. }
  193. static guint
  194. wave_table_size (GslOscWaveForm wave_form,
  195. gfloat mfreq)
  196. {
  197. /* have to return power of 2, and honour 8 <= size */
  198. /* FIXME: decide on other table sizes
  199. 10000: 256
  200. 5000: 512
  201. 2500: 1024
  202. 1250: 2048
  203. GSL_OSC_WAVE_SAW_FALL always huge buffers to guarantee pulse width stepping granularity
  204. */
  205. if (wave_form == GSL_OSC_WAVE_SAW_FALL)
  206. return 8192;
  207. return 2048;
  208. }
  209. static void
  210. fft_filter (guint n_values,
  211. gfloat *values, /* [0..n_values], n_values/2 complex values */
  212. gdouble scale_window,
  213. double (*window) (double))
  214. {
  215. guint i;
  216. n_values >>= 1;
  217. scale_window /= (gdouble) n_values;
  218. for (i = 0; i <= n_values; i++)
  219. {
  220. gdouble w = window (i * scale_window);
  221. values[i * 2] *= w;
  222. values[i * 2 + 1] *= w;
  223. }
  224. }
  225. static OscTableEntry*
  226. cache_table_ref_entry (GslOscWaveForm wave_form,
  227. double (*filter_func) (double),
  228. gfloat mfreq)
  229. {
  230. OscTableEntry *e = cache_table_entry_lookup_best (wave_form, (guint8*) filter_func, mfreq);
  231. if (e && !CACHE_MATCH_FREQ (mfreq, e->mfreq))
  232. e = NULL;
  233. if (!e)
  234. {
  235. guint size = wave_table_size (wave_form, mfreq);
  236. gfloat *values, *fft, step, min, max;
  237. /* size:
  238. * - OscTableEntry already contains the first float values
  239. * - we need n_values+1 adressable floats to provide values[0] == values[n_values]
  240. */
  241. e = g_malloc (sizeof (OscTableEntry) + sizeof (gfloat) * size);
  242. values = (gfloat*) &e->values[0];
  243. e->wave_form = wave_form;
  244. e->filter_func = (guint8*) filter_func;
  245. e->mfreq = mfreq;
  246. e->ref_count = 1;
  247. e->n_values = size;
  248. gsl_osc_wave_fill_buffer (e->wave_form, e->n_values, values);
  249. /* filter wave accordingly */
  250. gsl_osc_wave_extrema (e->n_values, values, &min, &max);
  251. fft = g_new (gfloat, e->n_values + 2); /* [0..n_values] for n_values/2 complex freqs */
  252. gsl_power2_fftar_simple (e->n_values, values, fft);
  253. step = e->mfreq * (gdouble) e->n_values;
  254. fft_filter (e->n_values, fft, step, filter_func);
  255. gsl_power2_fftsr_simple (e->n_values, fft, values);
  256. g_free (fft);
  257. gsl_osc_wave_normalize (e->n_values, values, (min + max) / 2, max);
  258. /* provide values[0]==values[n_values] */
  259. values[e->n_values] = values[0];
  260. /* pulse min/max pos extension */
  261. osc_wave_extrema_pos (e->n_values, values, &e->min_pos, &e->max_pos);
  262. /* insert into cache */
  263. cache_entries = g_bsearch_array_insert (cache_entries, &cache_taconfig, &e);
  264. }
  265. else
  266. e->ref_count++;
  267. return e;
  268. }
  269. static void
  270. cache_table_unref_entry (OscTableEntry *e)
  271. {
  272. g_return_if_fail (e->ref_count > 0);
  273. e->ref_count -= 1;
  274. if (e->ref_count == 0)
  275. {
  276. OscTableEntry **ep;
  277. guint i;
  278. ep = g_bsearch_array_lookup (cache_entries, &cache_taconfig, &e);
  279. i = g_bsearch_array_get_index (cache_entries, &cache_taconfig, ep);
  280. cache_entries = g_bsearch_array_remove (cache_entries, &cache_taconfig, i);
  281. }
  282. }
  283. GslOscTable*
  284. gsl_osc_table_create (gfloat mix_freq,
  285. GslOscWaveForm wave_form,
  286. double (*filter_func) (double),
  287. guint n_freqs,
  288. const gfloat *freqs)
  289. {
  290. GslOscTable *table;
  291. gfloat nyquist;
  292. guint i;
  293. g_return_val_if_fail (mix_freq > 0, NULL);
  294. g_return_val_if_fail (n_freqs > 0, NULL);
  295. g_return_val_if_fail (freqs != NULL, NULL);
  296. if (!cache_entries)
  297. cache_entries = g_bsearch_array_create (&cache_taconfig);
  298. table = gsl_new_struct (GslOscTable, 1);
  299. table->mix_freq = mix_freq;
  300. table->wave_form = wave_form;
  301. table->entry_array = g_bsearch_array_create (&osc_taconfig);
  302. nyquist = table->mix_freq * 0.5;
  303. if (wave_form == GSL_OSC_WAVE_PULSE_SAW)
  304. wave_form = GSL_OSC_WAVE_SAW_FALL;
  305. for (i = 0; i < n_freqs; i++)
  306. {
  307. OscTableEntry *e;
  308. gdouble mfreq = MIN (nyquist, freqs[i]);
  309. mfreq /= table->mix_freq;
  310. e = osc_table_entry_lookup_best (table, mfreq, NULL);
  311. if (!e || fabs (e->mfreq * table->mix_freq - mfreq * table->mix_freq) > OSC_FREQ_EPSILON)
  312. {
  313. e = cache_table_ref_entry (wave_form, filter_func, mfreq);
  314. table->entry_array = g_bsearch_array_insert (table->entry_array, &osc_taconfig, &e);
  315. }
  316. else if (e)
  317. OSC_DEBUG ("not inserting existing entry (freq=%f) for freq %f (nyquist=%f)",
  318. e->mfreq * table->mix_freq, mfreq * table->mix_freq, nyquist);
  319. }
  320. return table;
  321. }
  322. void
  323. gsl_osc_table_lookup (const GslOscTable *table,
  324. gfloat freq,
  325. GslOscWave *wave)
  326. {
  327. OscTableEntry *e;
  328. gfloat mfreq, min_mfreq;
  329. g_return_if_fail (table != NULL);
  330. g_return_if_fail (wave != NULL);
  331. mfreq = freq / table->mix_freq;
  332. e = osc_table_entry_lookup_best (table, mfreq, &min_mfreq);
  333. if (e)
  334. {
  335. guint32 int_one;
  336. gfloat float_one;
  337. wave->min_freq = min_mfreq * table->mix_freq;
  338. wave->max_freq = e->mfreq * table->mix_freq;
  339. wave->n_values = e->n_values;
  340. wave->values = e->values;
  341. wave->n_frac_bits = g_bit_storage (wave->n_values - 1);
  342. wave->n_frac_bits = 32 - wave->n_frac_bits;
  343. int_one = 1 << wave->n_frac_bits;
  344. wave->frac_bittqmask = int_one - 1;
  345. float_one = int_one;
  346. wave->freq_to_step = float_one * wave->n_values / table->mix_freq;
  347. wave->phase_to_pos = wave->n_values * float_one;
  348. wave->ifrac_to_float = 1.0 / float_one;
  349. /* pulse min/max pos extension */
  350. wave->min_pos = e->min_pos;
  351. wave->max_pos = e->max_pos;
  352. }
  353. else
  354. {
  355. /* shouldn't happen */
  356. OSC_DEBUG ("table lookup revealed NULL, empty table?");
  357. memset (wave, 0, sizeof (*wave));
  358. }
  359. }
  360. void
  361. gsl_osc_table_free (GslOscTable *table)
  362. {
  363. guint n;
  364. g_return_if_fail (table != NULL);
  365. n = g_bsearch_array_get_n_nodes (table->entry_array);
  366. while (n--)
  367. {
  368. OscTableEntry **ep;
  369. ep = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, n);
  370. cache_table_unref_entry (*ep);
  371. table->entry_array = g_bsearch_array_remove (table->entry_array, &osc_taconfig, n);
  372. }
  373. g_bsearch_array_free (table->entry_array, &osc_taconfig);
  374. gsl_delete_struct (GslOscTable, table);
  375. }
  376. void
  377. gsl_osc_cache_debug_dump (void)
  378. {
  379. OSC_DEBUG ("left in cache: %u", g_bsearch_array_get_n_nodes (cache_entries));
  380. }
  381. void
  382. gsl_osc_wave_fill_buffer (GslOscWaveForm type,
  383. guint n_values,
  384. gfloat *values)
  385. {
  386. gdouble max = n_values, hmax = max * 0.5, qmax = n_values * 0.25;
  387. gint i, half = n_values / 2, quarter = half / 2;
  388. switch (type)
  389. {
  390. gdouble frac, pos;
  391. case GSL_OSC_WAVE_SINE:
  392. for (i = 0; i < n_values; i++)
  393. {
  394. frac = ((gdouble) i) / max; /* [0..1[ */
  395. pos = frac * 2. * GSL_PI;
  396. values[i] = sin (pos);
  397. }
  398. break;
  399. case GSL_OSC_WAVE_SAW_RISE:
  400. for (i = 0; i < n_values; i++)
  401. {
  402. frac = ((gdouble) i) / max; /* [0..1[ */
  403. values[i] = 2.0 * frac - 1.0;
  404. }
  405. break;
  406. case GSL_OSC_WAVE_SAW_FALL:
  407. for (i = 0; i < n_values; i++)
  408. {
  409. frac = ((gdouble) i) / max; /* [0..1[ */
  410. values[i] = 1.0 - 2.0 * frac;
  411. }
  412. break;
  413. case GSL_OSC_WAVE_PEAK_RISE: /* spaced saw */
  414. for (i = 0; i < half; i++)
  415. {
  416. frac = ((gdouble) i) / hmax;
  417. values[i] = 2.0 * frac - 1.0;
  418. }
  419. for (; i < n_values; i++)
  420. values[i] = -1.0;
  421. break;
  422. case GSL_OSC_WAVE_PEAK_FALL: /* spaced saw */
  423. for (i = 0; i < half; i++)
  424. {
  425. frac = ((gdouble) i) / hmax;
  426. values[i] = 1.0 - 2.0 * frac;
  427. }
  428. for (; i < n_values; i++)
  429. values[i] = -1.0;
  430. break;
  431. case GSL_OSC_WAVE_TRIANGLE:
  432. for (i = 0; i < quarter; i++)
  433. {
  434. frac = ((gdouble) i) / qmax;
  435. values[i] = frac;
  436. }
  437. for (; i < half + quarter; i++)
  438. {
  439. frac = ((gdouble) i - quarter) / hmax;
  440. values[i] = 1.0 - 2.0 * frac;
  441. }
  442. for (; i < n_values; i++)
  443. {
  444. frac = ((gdouble) i - half - quarter) / qmax;
  445. values[i] = frac - 1.0;
  446. }
  447. break;
  448. case GSL_OSC_WAVE_MOOG_SAW:
  449. for (i = 0; i < half; i++)
  450. {
  451. frac = ((gdouble) i) / hmax;
  452. values[i] = 2.0 * frac - 1.0;
  453. }
  454. for (; i < n_values; i++)
  455. {
  456. frac = ((gdouble) i) / max;
  457. values[i] = 1.0 - 2.0 * frac;
  458. }
  459. break;
  460. case GSL_OSC_WAVE_SQUARE:
  461. for (i = 0; i < half; i++)
  462. values[i] = 1.0;
  463. for (; i < n_values; i++)
  464. values[i] = -1.0;
  465. break;
  466. default:
  467. g_critical ("%s: invalid wave form id (%u)", G_STRLOC, type);
  468. case GSL_OSC_WAVE_NONE:
  469. for (i = 0; i < n_values; i++)
  470. values[i] = 0;
  471. break;
  472. }
  473. }
  474. static void
  475. osc_wave_extrema_pos (guint n_values,
  476. const gfloat *values,
  477. guint *minp_p,
  478. guint *maxp_p)
  479. {
  480. guint i, minp = 0, maxp = 0;
  481. gfloat min = values[0], max = min;
  482. for (i = 1; i < n_values; i++)
  483. {
  484. if (values[i] > max)
  485. {
  486. max = values[i];
  487. maxp = i;
  488. }
  489. else if (values[i] < min)
  490. {
  491. min = values[i];
  492. minp = i;
  493. }
  494. }
  495. *minp_p = minp;
  496. *maxp_p = maxp;
  497. }
  498. void
  499. gsl_osc_wave_extrema (guint n_values,
  500. const gfloat *values,
  501. gfloat *min_p,
  502. gfloat *max_p)
  503. {
  504. guint minp, maxp;
  505. g_return_if_fail (n_values > 0 && values != NULL && min_p != NULL && max_p != NULL);
  506. osc_wave_extrema_pos (n_values, values, &minp, &maxp);
  507. *min_p = values[minp];
  508. *max_p = values[maxp];
  509. }
  510. void
  511. gsl_osc_wave_adjust_range (guint n_values,
  512. gfloat *values,
  513. gfloat min,
  514. gfloat max,
  515. gfloat new_center,
  516. gfloat new_max)
  517. {
  518. gfloat center;
  519. guint i;
  520. g_return_if_fail (n_values > 0 && values != NULL);
  521. center = (min + max) / 2;
  522. center = new_center - center;
  523. min = fabs (min + center);
  524. max = fabs (max + center);
  525. if (min > max)
  526. max = min;
  527. if (max > GSL_FLOAT_MIN_NORMAL)
  528. max = new_max / max;
  529. else
  530. max = 0;
  531. for (i = 0; i < n_values; i++)
  532. values[i] = (values[i] + center) * max;
  533. }
  534. void
  535. gsl_osc_wave_normalize (guint n_values,
  536. gfloat *values,
  537. gfloat new_center,
  538. gfloat new_max)
  539. {
  540. gfloat min, max;
  541. guint i;
  542. g_return_if_fail (n_values > 0 && values != NULL);
  543. min = values[0];
  544. max = min;
  545. for (i = 1; i < n_values; i++)
  546. {
  547. register gfloat v = values[i];
  548. max = MAX (max, v);
  549. min = MIN (min, v);
  550. }
  551. gsl_osc_wave_adjust_range (n_values, values, min, max, new_center, new_max);
  552. }