fluid_seq.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:30k
源码类别:

midi

开发平台:

C/C++

  1. /* FluidSynth - A Software Synthesizer
  2.  *
  3.  * Copyright (C) 2003  Peter Hanappe and others.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 of
  8.  * the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. /*
  21.   2002 : API design by Peter Hanappe and Antoine Schmitt
  22.   August 2002 : Implementation by Antoine Schmitt as@gratin.org
  23.   as part of the infiniteCD author project
  24.   http://www.infiniteCD.org/
  25. */
  26. #include "fluid_event_priv.h"
  27. #include "fluidsynth_priv.h" // FLUID_NEW, etc
  28. #include "fluid_sys.h" // timer, threads, etc...
  29. #include "fluid_list.h"
  30. /***************************************************************
  31.  *
  32.  *                           SEQUENCER
  33.  */
  34. #define FLUID_SEQUENCER_EVENTS_MAX 1000
  35. /* Private data for SEQUENCER */
  36. struct _fluid_sequencer_t {
  37. unsigned int startMs;
  38. gint currentMs;
  39. gboolean useSystemTimer;
  40. double scale; // ticks per second
  41. fluid_list_t* clients;
  42. short clientsID;
  43. /* for queue + heap */
  44. fluid_evt_entry* preQueue;
  45. fluid_evt_entry* preQueueLast;
  46. fluid_timer_t* timer;
  47. int queue0StartTime;
  48. short prevCellNb;
  49. fluid_evt_entry* queue0[256][2];
  50. fluid_evt_entry* queue1[255][2];
  51. fluid_evt_entry* queueLater;
  52. fluid_evt_heap_t* heap;
  53. fluid_mutex_t mutex;
  54. #if FLUID_SEQ_WITH_TRACE
  55. char *tracebuf;
  56. char *traceptr;
  57. int tracelen;
  58. #endif
  59. };
  60. /* Private data for clients */
  61. typedef struct _fluid_sequencer_client_t {
  62. short id;
  63. char* name;
  64. fluid_event_callback_t callback;
  65. void* data;
  66. } fluid_sequencer_client_t;
  67. /* prototypes */
  68. static short _fluid_seq_queue_init(fluid_sequencer_t* seq, int nbEvents);
  69. static void _fluid_seq_queue_end(fluid_sequencer_t* seq);
  70. static short _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt);
  71. static void _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type);
  72. static int _fluid_seq_queue_process(void* data, unsigned int msec); // callback from timer
  73. static void _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry);
  74. static void _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* temp);
  75. static void _fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq);
  76. static void _fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last);
  77. /* API implementation */
  78. /**
  79.  * Create a new sequencer object which uses the system timer.  Use
  80.  * new_fluid_sequencer2() to specify whether the system timer or
  81.  * fluid_sequencer_process() is used to advance the sequencer.
  82.  * @return New sequencer instance
  83.  */
  84. fluid_sequencer_t*
  85. new_fluid_sequencer (void)
  86. {
  87. return new_fluid_sequencer2 (TRUE);
  88. }
  89. /**
  90.  * Create a new sequencer object.
  91.  * @param use_system_timer If TRUE, sequencer will advance at the rate of the
  92.  *   system clock. If FALSE, call fluid_sequencer_process() to advance
  93.  *   the sequencer.
  94.  * @return New sequencer instance
  95.  * @since 1.1.0
  96.  */
  97. fluid_sequencer_t*
  98. new_fluid_sequencer2 (int use_system_timer)
  99. {
  100. fluid_sequencer_t* seq;
  101. seq = FLUID_NEW(fluid_sequencer_t);
  102. if (seq == NULL) {
  103. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  104. return NULL;
  105. }
  106. FLUID_MEMSET(seq, 0, sizeof(fluid_sequencer_t));
  107. seq->scale = 1000; // default value
  108. seq->useSystemTimer = use_system_timer ? TRUE : FALSE;
  109. seq->startMs = seq->useSystemTimer ? fluid_curtime() : 0;
  110. seq->clients = NULL;
  111. seq->clientsID = 0;
  112. if (-1 == _fluid_seq_queue_init(seq, FLUID_SEQUENCER_EVENTS_MAX)) {
  113. FLUID_FREE(seq);
  114. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  115. return NULL;
  116. }
  117. #if FLUID_SEQ_WITH_TRACE
  118. seq->tracelen = 1024*100;
  119. seq->tracebuf = (char *)FLUID_MALLOC(seq->tracelen);
  120. if (seq->tracebuf == NULL) {
  121.   _fluid_seq_queue_end(seq);
  122.   FLUID_FREE(seq);
  123. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  124. return NULL;
  125. }
  126. seq->traceptr = seq->tracebuf;
  127. #endif
  128. return(seq);
  129. }
  130. /**
  131.  * Free a sequencer object.
  132.  * @param seq Sequencer to delete
  133.  */
  134. void
  135. delete_fluid_sequencer (fluid_sequencer_t* seq)
  136. {
  137. if (seq == NULL) {
  138. return;
  139. }
  140. /* cleanup clients */
  141. while (seq->clients) {
  142. fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)seq->clients->data;
  143. fluid_sequencer_unregister_client(seq, client->id);
  144. }
  145. _fluid_seq_queue_end(seq);
  146. /* if (seq->clients) {
  147. fluid_list_t *tmp = seq->clients;
  148. while (tmp != NULL) {
  149. fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
  150. if (client->name) FLUID_FREE(client->name);
  151. tmp = tmp->next;
  152. }
  153. delete_fluid_list(seq->clients);
  154. seq->clients = NULL;
  155. }*/
  156. #if FLUID_SEQ_WITH_TRACE
  157. if (seq->tracebuf != NULL)
  158. FLUID_FREE(seq->tracebuf);
  159. seq->tracebuf = NULL;
  160. #endif
  161. FLUID_FREE(seq);
  162. }
  163. /**
  164.  * Check if a sequencer is using the system timer or not.
  165.  * @param seq Sequencer object
  166.  * @return TRUE if system timer is being used, FALSE otherwise.
  167.  * @since 1.1.0
  168.  */
  169. int 
  170. fluid_sequencer_get_use_system_timer (fluid_sequencer_t* seq)
  171. {
  172. return seq->useSystemTimer ? 1 : 0;
  173. }
  174. #if FLUID_SEQ_WITH_TRACE
  175. /* trace */
  176. void
  177. fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...)
  178. {
  179. va_list args;
  180. int len, remain = seq->tracelen - (seq->traceptr - seq->tracebuf);
  181. if (remain <= 0) return;
  182. va_start (args, fmt);
  183. len = vsnprintf(seq->traceptr, remain, fmt, args);
  184. va_end (args);
  185. if (len > 0) {
  186. if (len <= remain) {
  187. // all written, with 0 at end
  188. seq->traceptr += len;
  189. } else {
  190. // not enough room, set to end
  191. seq->traceptr = seq->tracebuf + seq->tracelen;
  192. }
  193. }
  194. return;
  195. }
  196. /**
  197.  * Clear sequencer trace buffer.
  198.  * @param seq Sequencer object
  199.  */
  200. void
  201. fluid_seq_cleartrace(fluid_sequencer_t* seq)
  202. {
  203. seq->traceptr = seq->tracebuf;
  204. }
  205. /**
  206.  * Get sequencer trace buffer.
  207.  * @param seq Sequencer object
  208.  */
  209. char *
  210. fluid_seq_gettrace(fluid_sequencer_t* seq)
  211. {
  212. return seq->tracebuf;
  213. }
  214. #else
  215. void fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...) {}
  216. #endif // FLUID_SEQ_WITH_TRACE
  217. /* clients */
  218. /**
  219.  * Register a sequencer client.
  220.  * @param seq Sequencer object
  221.  * @param name Name of sequencer client
  222.  * @param callback Sequencer client callback or NULL for a source client.
  223.  * @param data User data to pass to the a callback
  224.  * @return Unique sequencer ID or #FLUID_FAILED on error
  225.  *
  226.  * Clients can be sources or destinations of events.  Sources don't need to
  227.  * register a callback.
  228.  */
  229. short
  230. fluid_sequencer_register_client (fluid_sequencer_t* seq, const char *name,
  231.                                  fluid_event_callback_t callback, void* data)
  232. {
  233. fluid_sequencer_client_t * client;
  234. char * nameCopy;
  235. client = FLUID_NEW(fluid_sequencer_client_t);
  236. if (client == NULL) {
  237. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  238. return FLUID_FAILED;
  239. }
  240. nameCopy = FLUID_STRDUP(name);
  241. if (nameCopy == NULL) {
  242. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  243. return FLUID_FAILED;
  244. }
  245. seq->clientsID++;
  246. client->name = nameCopy;
  247. client->id = seq->clientsID;
  248. client->callback = callback;
  249. client->data = data;
  250. seq->clients = fluid_list_append(seq->clients, (void *)client);
  251. return (client->id);
  252. }
  253. /**
  254.  * Unregister a previously registered client.
  255.  * @param seq Sequencer object
  256.  * @param id Client ID as returned by fluid_sequencer_register_client().
  257.  */
  258. void
  259. fluid_sequencer_unregister_client (fluid_sequencer_t* seq, short id)
  260. {
  261. fluid_list_t *tmp;
  262. fluid_event_t* evt;
  263. if (seq->clients == NULL) return;
  264. evt = new_fluid_event();
  265. if (evt != NULL) {
  266. fluid_event_unregistering(evt);
  267. fluid_event_set_dest(evt, id);
  268. }
  269. tmp = seq->clients;
  270. while (tmp) {
  271.    fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
  272.    if (client->id == id) {
  273. /* What should we really do if evt is null due to out-of-memory? */
  274. if (client->callback != NULL && evt != NULL)
  275. (client->callback)(fluid_sequencer_get_tick(seq),
  276.  evt, seq, client->data);
  277.     if (client->name)
  278. FLUID_FREE(client->name);
  279. seq->clients = fluid_list_remove_link(seq->clients, tmp);
  280. delete1_fluid_list(tmp);
  281. FLUID_FREE(client);
  282. delete_fluid_event(evt);
  283. return;
  284.    }
  285.     tmp = tmp->next;
  286. }
  287. delete_fluid_event(evt);
  288. return;
  289. }
  290. /**
  291.  * Count a sequencers registered clients.
  292.  * @param seq Sequencer object
  293.  * @return Count of sequencer clients.
  294.  */
  295. int
  296. fluid_sequencer_count_clients(fluid_sequencer_t* seq)
  297. {
  298. if (seq->clients == NULL)
  299. return 0;
  300. return fluid_list_size(seq->clients);
  301. }
  302. /**
  303.  * Get a client ID from its index (order in which it was registered).
  304.  * @param seq Sequencer object
  305.  * @param index Index of register client
  306.  * @return Client ID or #FLUID_FAILED if not found
  307.  */
  308. short fluid_sequencer_get_client_id (fluid_sequencer_t* seq, int index)
  309. {
  310. fluid_list_t *tmp = fluid_list_nth(seq->clients, index);
  311. if (tmp == NULL) {
  312. return FLUID_FAILED;
  313. } else {
  314. fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
  315. return client->id;
  316. }
  317. }
  318. /**
  319.  * Get the name of a registered client.
  320.  * @param seq Sequencer object
  321.  * @param id Client ID
  322.  * @return Client name or NULL if not found.  String is internal and should not
  323.  *   be modified or freed.
  324.  */
  325. char *
  326. fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id)
  327. {
  328. fluid_list_t *tmp;
  329. if (seq->clients == NULL)
  330. return NULL;
  331. tmp = seq->clients;
  332. while (tmp) {
  333.    fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
  334.    if (client->id == id)
  335.    return client->name;
  336.     tmp = tmp->next;
  337. }
  338. return NULL;
  339. }
  340. /**
  341.  * Check if a client is a destination client.
  342.  * @param seq Sequencer object
  343.  * @param id Client ID
  344.  * @return TRUE if client is a destination client, FALSE otherwise or if not found
  345.  */
  346. int
  347. fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id)
  348. {
  349. fluid_list_t *tmp;
  350. if (seq->clients == NULL) return FALSE;
  351. tmp = seq->clients;
  352. while (tmp) {
  353.    fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
  354.    if (client->id == id)
  355.    return (client->callback != NULL);
  356.     tmp = tmp->next;
  357. }
  358. return FALSE;
  359. }
  360. /**
  361.  * Send an event immediately.
  362.  * @param seq Sequencer object
  363.  * @param evt Event to send (copied)
  364.  */
  365. /* Event not actually copied, but since its used immediately it virtually is. */
  366. void
  367. fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt)
  368. {
  369. short destID = fluid_event_get_dest(evt);
  370. /* find callback */
  371. fluid_list_t *tmp = seq->clients;
  372. while (tmp) {
  373.    fluid_sequencer_client_t *dest = (fluid_sequencer_client_t*)tmp->data;
  374.    if (dest->id == destID) {
  375. if (dest->callback)
  376. (dest->callback)(fluid_sequencer_get_tick(seq),
  377.  evt, seq, dest->data);
  378. return;
  379.    }
  380.     tmp = tmp->next;
  381. }
  382. }
  383. /**
  384.  * Schedule an event for sending at a later time.
  385.  * @param seq Sequencer object
  386.  * @param evt Event to send
  387.  * @param time Time value in ticks (in milliseconds with the default time scale of 1000).
  388.  * @param absolute TRUE if a time is absolute sequencer time (time since sequencer
  389.  *   creation), FALSE if relative to current time.
  390.  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
  391.  */
  392. int
  393. fluid_sequencer_send_at (fluid_sequencer_t* seq, fluid_event_t* evt,
  394.                          unsigned int time, int absolute)
  395. {
  396. unsigned int now = fluid_sequencer_get_tick(seq);
  397. /* set absolute */
  398. if (!absolute)
  399. time = now + time;
  400. /* time stamp event */
  401. fluid_event_set_time(evt, time);
  402. /* queue for processing later */
  403. return _fluid_seq_queue_pre_insert(seq, evt);
  404. }
  405. /**
  406.  * Remove events from the event queue.
  407.  * @param seq Sequencer object
  408.  * @param source Source client ID to match or -1 for wildcard
  409.  * @param dest Destination client ID to match or -1 for wildcard
  410.  * @param type Event type to match or -1 for wildcard (#fluid_seq_event_type)
  411.  */
  412. void
  413. fluid_sequencer_remove_events (fluid_sequencer_t* seq, short source,
  414.                                short dest, int type)
  415. {
  416. _fluid_seq_queue_pre_remove(seq, source, dest, type);
  417. }
  418. /*************************************
  419. time
  420. **************************************/
  421. /**
  422.  * Get the current tick of a sequencer.
  423.  * @param seq Sequencer object
  424.  * @return Current tick value
  425.  */
  426. unsigned int
  427. fluid_sequencer_get_tick (fluid_sequencer_t* seq)
  428. {
  429. unsigned int absMs = seq->useSystemTimer ? (int) fluid_curtime() : g_atomic_int_get(&seq->currentMs);
  430. double nowFloat;
  431. unsigned int now;
  432. nowFloat = ((double)(absMs - seq->startMs))*seq->scale/1000.0f;
  433. now = nowFloat;
  434. return now;
  435. }
  436. /**
  437.  * Set the time scale of a sequencer.
  438.  * @param seq Sequencer object
  439.  * @param scale Sequencer scale value in ticks per second
  440.  *   (default is 1000 for 1 tick per millisecond, max is 1000.0)
  441.  *
  442.  * If there are already scheduled events in the sequencer and the scale is changed
  443.  * the events are adjusted accordingly.
  444.  */
  445. void
  446. fluid_sequencer_set_time_scale (fluid_sequencer_t* seq, double scale)
  447. {
  448. if (scale <= 0) {
  449. fluid_log(FLUID_WARN, "sequencer: scale <= 0 : %fn", scale);
  450. return;
  451. }
  452. if (scale > 1000.0)
  453. // Otherwise : problems with the timer = 0ms...
  454. scale = 1000.0;
  455. if (seq->scale != scale) {
  456. double oldScale = seq->scale;
  457. // stop timer
  458. if (seq->timer) {
  459. delete_fluid_timer(seq->timer);
  460. seq->timer = NULL;
  461. }
  462. seq->scale = scale;
  463. // change start0 so that cellNb is preserved
  464. seq->queue0StartTime =  (seq->queue0StartTime + seq->prevCellNb)*(seq->scale/oldScale) - seq->prevCellNb;
  465. // change all preQueue events for new scale
  466. {
  467. fluid_evt_entry* tmp;
  468. tmp = seq->preQueue;
  469. while (tmp) {
  470. if (tmp->entryType == FLUID_EVT_ENTRY_INSERT)
  471. tmp->evt.time = tmp->evt.time*seq->scale/oldScale;
  472. tmp = tmp->next;
  473. }
  474. }
  475. /* re-start timer */
  476. if (seq->useSystemTimer) {
  477. seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process, (void *)seq, TRUE, FALSE, TRUE);
  478. }
  479. }
  480. }
  481. /**
  482.  * Get a sequencer's time scale.
  483.  * @param seq Sequencer object.
  484.  * @return Time scale value in ticks per second.
  485.  */
  486. double
  487. fluid_sequencer_get_time_scale(fluid_sequencer_t* seq)
  488. {
  489. return seq->scale;
  490. }
  491. /**********************
  492.       the queue
  493. **********************/
  494. /*
  495.   The queue stores all future events to be processed.
  496.   Data structures
  497.   There is a heap, allocated at init time, for managing a pool
  498.   of event entries, that is description of an event, its time,
  499.   and whether it is a normal event or a removal command.
  500.   The queue is separated in two arrays, and a list.  The first
  501.   array 'queue0' corresponds to the events to be sent in the
  502.   next 256 ticks (0 to 255), the second array 'queue1' contains
  503.   the events to be send from now+256 to now+65535. The list
  504.   called 'queueLater' contains the events to be sent later than
  505.   that. In each array, one cell contains a list of events having
  506.   the same time (in the queue0 array), or the same time/256 (in
  507.   the queue1 array), and a pointer to the last event in the list
  508.   of the cell so as to be able to insert fast at the end of the
  509.   list (i.e. a cell = 2 pointers).  The 'queueLater' list is
  510.   ordered by time and by post time.  This way, inserting 'soon'
  511.   events is fast (below 65535 ticks, that is about 1 minute if 1
  512.   tick=1ms).  Inserting later events is more slow, but this is a
  513.   realtime engine, isn't it ?
  514.   The queue0 starts at queue0StartTime.  When 256 ticks have
  515.   elapsed, the queue0 array is emptied, and the first cell of
  516.   the queue1 array is expanded in the queue0 array, according to
  517.   the time of each event. The queue1 array is shifted to the
  518.   left, and the first events of the queueLater list are inserte
  519.   in the last cell of the queue1 array.
  520.   We remember the previously managed cell in queue0 in the
  521.   prevCellNb variable. When processing the current cell, we
  522.   process the events in between (late events).
  523.   Functions
  524.   The main thread functions first get an event entry from the
  525.   heap, and copy the given event into it, then merely enqueue it
  526.   in a preQueue. This is in order to protect the data structure:
  527.   everything is managed in the callback (thread or interrupt,
  528.   depending on the architecture).
  529.   All queue data structure management is done in a timer
  530.   callback: '_fluid_seq_queue_process'.  The
  531.   _fluid_seq_queue_process function first process the preQueue,
  532.   inserting or removing event entrys from the queue, then
  533.   processes the queue, by sending events ready to be sent at the
  534.   current time.
  535.   Critical sections between the main thread (or app) and the
  536.   sequencer thread (or interrupt) are:
  537.   - the heap management (if two threads get a free event at the
  538.   same time)
  539.   - the preQueue access.
  540.   These are really small and fast sections (merely a pointer or
  541.   two changing value). They are not protected by a mutex for now
  542.   (August 2002). Waiting for crossplatform mutex solutions. When
  543.   changing this code, beware that the
  544.   _fluid_seq_queue_pre_insert function may be called by the
  545.   callback of the queue thread (ex : a note event inserts a
  546.   noteoff event).
  547. */
  548. /********************/
  549. /*       API        */
  550. /********************/
  551. static short
  552. _fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents)
  553. {
  554. seq->heap = _fluid_evt_heap_init(maxEvents);
  555. if (seq->heap == NULL) {
  556. fluid_log(FLUID_PANIC, "sequencer: Out of memoryn");
  557. return -1;
  558. }
  559. seq->preQueue = NULL;
  560. seq->preQueueLast = NULL;
  561. FLUID_MEMSET(seq->queue0, 0, 2*256*sizeof(fluid_evt_entry *));
  562. FLUID_MEMSET(seq->queue1, 0, 2*255*sizeof(fluid_evt_entry *));
  563. seq->queueLater = NULL;
  564. seq->queue0StartTime = fluid_sequencer_get_tick(seq);
  565. seq->prevCellNb = -1;
  566. fluid_mutex_init(seq->mutex);
  567. /* start timer */
  568. if (seq->useSystemTimer) {
  569. seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process,
  570.      (void *)seq, TRUE, FALSE, TRUE);
  571. }
  572. return (0);
  573. }
  574. static void
  575. _fluid_seq_queue_end(fluid_sequencer_t* seq)
  576. {
  577. int i;
  578. /* free all remaining events */
  579. _fluid_free_evt_queue(&seq->preQueue, &seq->preQueueLast);
  580. for (i = 0; i < 256; i++) 
  581. _fluid_free_evt_queue(&(seq->queue0[i][0]), &(seq->queue0[i][1]));
  582. for (i = 0; i < 255; i++) 
  583. _fluid_free_evt_queue(&(seq->queue1[i][0]), &(seq->queue1[i][1]));
  584. _fluid_free_evt_queue(&seq->queueLater, NULL);
  585. if (seq->timer) {
  586. delete_fluid_timer(seq->timer);
  587. seq->timer = NULL;
  588. }
  589. if (seq->heap) {
  590. _fluid_evt_heap_free(seq->heap);
  591. seq->heap = NULL;
  592. }
  593. fluid_mutex_destroy(seq->mutex);
  594. }
  595. /********************/
  596. /* queue management */
  597. /********************/
  598. /* Create event_entry and append to the preQueue.
  599.  * May be called from the main thread (usually) but also recursively
  600.  * from the queue thread, when a callback itself does an insert... */
  601. static short
  602. _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt)
  603. {
  604. fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap);
  605. if (evtentry == NULL) {
  606. /* should not happen */
  607. fluid_log(FLUID_PANIC, "sequencer: no more free eventsn");
  608. return -1;
  609. }
  610. evtentry->next = NULL;
  611. evtentry->entryType = FLUID_EVT_ENTRY_INSERT;
  612. FLUID_MEMCPY(&(evtentry->evt), evt, sizeof(fluid_event_t));
  613. fluid_mutex_lock(seq->mutex);
  614. /* append to preQueue */
  615. if (seq->preQueueLast) {
  616. seq->preQueueLast->next = evtentry;
  617. } else {
  618. seq->preQueue = evtentry;
  619. }
  620. seq->preQueueLast = evtentry;
  621. fluid_mutex_unlock(seq->mutex);
  622. return (0);
  623. }
  624. /* Create event_entry and append to the preQueue.
  625.  * May be called from the main thread (usually) but also recursively
  626.  * from the queue thread, when a callback itself does an insert... */
  627. static void
  628. _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type)
  629. {
  630. fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap);
  631. if (evtentry == NULL) {
  632. /* should not happen */
  633. fluid_log(FLUID_PANIC, "sequencer: no more free eventsn");
  634. return;
  635. }
  636. evtentry->next = NULL;
  637. evtentry->entryType = FLUID_EVT_ENTRY_REMOVE;
  638. {
  639. fluid_event_t* evt = &(evtentry->evt);
  640. fluid_event_set_source(evt, src);
  641. fluid_event_set_source(evt, src);
  642. fluid_event_set_dest(evt, dest);
  643. evt->type = type;
  644. }
  645. fluid_mutex_lock(seq->mutex);
  646. /* append to preQueue */
  647. if (seq->preQueueLast) {
  648. seq->preQueueLast->next = evtentry;
  649. } else {
  650. seq->preQueue = evtentry;
  651. }
  652. seq->preQueueLast = evtentry;
  653. fluid_mutex_unlock(seq->mutex);
  654. return;
  655. }
  656. static void
  657. _fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last)
  658. {
  659. fluid_evt_entry* tmp2;
  660. fluid_evt_entry* tmp = *first;
  661. while (tmp != NULL) {
  662. tmp2 = tmp->next;
  663. FLUID_FREE(tmp);
  664. tmp = tmp2;
  665. }
  666. *first = NULL;
  667. if (last != NULL) {
  668. *last = NULL;
  669. }
  670. }
  671. /* Callback from timer (may be in a different thread, or in an interrupt) */
  672. static int
  673. _fluid_seq_queue_process(void* data, unsigned int msec)
  674. {
  675. fluid_sequencer_t* seq = (fluid_sequencer_t *)data;
  676. fluid_sequencer_process(seq, msec);
  677. /* continue timer */
  678. return 1;
  679. }
  680. /** 
  681.  * Advance a sequencer that isn't using the system timer.
  682.  * @param seq Sequencer object
  683.  * @param msec Time to advance sequencer to (absolute time since sequencer start).
  684.  * @since 1.1.0
  685.  */
  686. void
  687. fluid_sequencer_process(fluid_sequencer_t* seq, unsigned int msec)
  688. {
  689. /* process prequeue */
  690. fluid_evt_entry* tmp;
  691. fluid_evt_entry* next;
  692. fluid_mutex_lock(seq->mutex);
  693. /* get the preQueue */
  694. tmp = seq->preQueue;
  695. seq->preQueue = NULL;
  696. seq->preQueueLast = NULL;
  697. fluid_mutex_unlock(seq->mutex);
  698. /* walk all the preQueue and process them in order : inserts and removes */
  699. while (tmp) {
  700. next = tmp->next;
  701. if (tmp->entryType == FLUID_EVT_ENTRY_REMOVE) {
  702. _fluid_seq_queue_remove_entries_matching(seq, tmp);
  703. } else {
  704. _fluid_seq_queue_insert_entry(seq, tmp);
  705. }
  706. tmp = next;
  707. }
  708. /* send queued events */
  709. g_atomic_int_set(&seq->currentMs, msec);
  710. _fluid_seq_queue_send_queued_events(seq);
  711. }
  712. #if 0
  713. static void
  714. _fluid_seq_queue_print_later(fluid_sequencer_t* seq)
  715. {
  716. int count = 0;
  717. fluid_evt_entry* tmp = seq->queueLater;
  718. printf("queueLater:n");
  719. while (tmp) {
  720. unsigned int delay = tmp->evt.time - seq->queue0StartTime;
  721. printf("queueLater: Delay = %in", delay);
  722. tmp = tmp->next;
  723. count++;
  724. }
  725. printf("queueLater: Total of %i eventsn", count);
  726. }
  727. #endif
  728. static void
  729. _fluid_seq_queue_insert_queue0(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell)
  730. {
  731. if (seq->queue0[cell][1] == NULL) {
  732. seq->queue0[cell][1] = seq->queue0[cell][0] = tmp;
  733. } else {
  734. seq->queue0[cell][1]->next = tmp;
  735. seq->queue0[cell][1] = tmp;
  736. }
  737. tmp->next = NULL;
  738. }
  739. static void
  740. _fluid_seq_queue_insert_queue1(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell)
  741. {
  742. if (seq->queue1[cell][1] == NULL) {
  743. seq->queue1[cell][1] = seq->queue1[cell][0] = tmp;
  744. } else {
  745. seq->queue1[cell][1]->next = tmp;
  746. seq->queue1[cell][1] = tmp;
  747. }
  748. tmp->next = NULL;
  749. }
  750. static void
  751. _fluid_seq_queue_insert_queue_later(fluid_sequencer_t* seq, fluid_evt_entry* evtentry)
  752. {
  753. fluid_evt_entry* prev;
  754. fluid_evt_entry* tmp;
  755. unsigned int time = evtentry->evt.time;
  756. /* insert in 'queueLater', after the ones that have the same
  757.  * time */
  758. /* first? */
  759. if ((seq->queueLater == NULL)
  760.     || (seq->queueLater->evt.time > time)) {
  761. evtentry->next = seq->queueLater;
  762. seq->queueLater = evtentry;
  763. return;
  764. }
  765. /* walk queueLater */
  766. /* this is the only slow thing : if the event is more
  767.    than 65535 ticks after the current time */
  768. prev = seq->queueLater;
  769. tmp = prev->next;
  770. while (tmp) {
  771. if (tmp->evt.time > time) {
  772. /* insert before tmp */
  773. evtentry->next = tmp;
  774. prev->next = evtentry;
  775. return;
  776. }
  777. prev = tmp;
  778. tmp = prev->next;
  779. }
  780. /* last */
  781. evtentry->next = NULL;
  782. prev->next = evtentry;
  783. }
  784. static void
  785. _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry)
  786. {
  787. /* time is relative to seq origin, in ticks */
  788. fluid_event_t * evt = &(evtentry->evt);
  789. unsigned int time = evt->time;
  790. unsigned int delay;
  791. if (seq->queue0StartTime > 0) {
  792. /* queue0StartTime could be < 0 if the scale changed a
  793.    lot early, breaking the following comparison
  794. */
  795. if (time < (unsigned int)seq->queue0StartTime) {
  796. /* we are late, send now */
  797. fluid_sequencer_send_now(seq, evt);
  798. _fluid_seq_heap_set_free(seq->heap, evtentry);
  799. return;
  800. }
  801. }
  802. if (seq->prevCellNb >= 0) {
  803. /* prevCellNb could be -1 is seq was just started - unlikely */
  804. /* prevCellNb can also be -1 if cellNb was reset to 0 in
  805.    _fluid_seq_queue_send_queued_events() */
  806. if (time <= (unsigned int)(seq->queue0StartTime + seq->prevCellNb)) {
  807. /* we are late, send now */
  808. fluid_sequencer_send_now(seq, evt);
  809. _fluid_seq_heap_set_free(seq->heap, evtentry);
  810. return;
  811. }
  812. }
  813. delay = time - seq->queue0StartTime;
  814. if (delay > 65535) {
  815. _fluid_seq_queue_insert_queue_later(seq, evtentry);
  816. } else if (delay > 255) {
  817. _fluid_seq_queue_insert_queue1(seq, evtentry, delay/256 - 1);
  818. } else {
  819. _fluid_seq_queue_insert_queue0(seq, evtentry, delay);
  820. }
  821. }
  822. static int
  823. _fluid_seq_queue_matchevent(fluid_event_t* evt, int templType, short templSrc, short templDest)
  824. {
  825. int eventType;
  826. if (templSrc != -1 && templSrc != fluid_event_get_source(evt))
  827. return 0;
  828. if (templDest != -1 && templDest != fluid_event_get_dest(evt))
  829. return 0;
  830. if (templType == -1)
  831. return 1;
  832. eventType = fluid_event_get_type(evt);
  833. if (templType == eventType)
  834. return 1;
  835. if (templType == FLUID_SEQ_ANYCONTROLCHANGE)
  836. if (eventType == FLUID_SEQ_PITCHBEND ||
  837.     eventType == FLUID_SEQ_MODULATION ||
  838.     eventType == FLUID_SEQ_SUSTAIN ||
  839.     eventType == FLUID_SEQ_PAN ||
  840.     eventType == FLUID_SEQ_VOLUME ||
  841.     eventType == FLUID_SEQ_REVERBSEND ||
  842.     eventType == FLUID_SEQ_CONTROLCHANGE ||
  843.     eventType == FLUID_SEQ_CHORUSSEND)
  844. return 1;
  845. return 0;
  846. }
  847. static void
  848. _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* templ)
  849. {
  850. /* we walk everything : this is slow, but that is life */
  851. int i, type;
  852. short src, dest;
  853. src = templ->evt.src;
  854. dest = templ->evt.dest;
  855. type = templ->evt.type;
  856. /* we can set it free now */
  857. _fluid_seq_heap_set_free(seq->heap, templ);
  858. /* queue0 */
  859. for (i = 0 ; i < 256 ; i++) {
  860. fluid_evt_entry* tmp = seq->queue0[i][0];
  861. fluid_evt_entry* prev = NULL;
  862. while (tmp) {
  863. /* remove and/or walk */
  864. if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) {
  865. /* remove */
  866. if (prev) {
  867. prev->next = tmp->next;
  868. if (tmp == seq->queue0[i][1]) // last one in list
  869. seq->queue0[i][1] = prev;
  870. _fluid_seq_heap_set_free(seq->heap, tmp);
  871. tmp = prev->next;
  872. } else {
  873. /* first one in list */
  874. seq->queue0[i][0] = tmp->next;
  875. if (tmp == seq->queue0[i][1]) // last one in list
  876. seq->queue0[i][1] = NULL;
  877. _fluid_seq_heap_set_free(seq->heap, tmp);
  878. tmp = seq->queue0[i][0];
  879. }
  880. } else {
  881. prev = tmp;
  882. tmp = prev->next;
  883. }
  884. }
  885. }
  886. /* queue1 */
  887. for (i = 0 ; i < 255 ; i++) {
  888. fluid_evt_entry* tmp = seq->queue1[i][0];
  889. fluid_evt_entry* prev = NULL;
  890. while (tmp) {
  891. if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) {
  892. /* remove */
  893. if (prev) {
  894. prev->next = tmp->next;
  895. if (tmp == seq->queue1[i][1]) // last one in list
  896. seq->queue1[i][1] = prev;
  897. _fluid_seq_heap_set_free(seq->heap, tmp);
  898. tmp = prev->next;
  899. } else {
  900. /* first one in list */
  901. seq->queue1[i][0] = tmp->next;
  902. if (tmp == seq->queue1[i][1]) // last one in list
  903. seq->queue1[i][1] = NULL;
  904. _fluid_seq_heap_set_free(seq->heap, tmp);
  905. tmp = seq->queue1[i][0];
  906. }
  907. } else {
  908. prev = tmp;
  909. tmp = prev->next;
  910. }
  911. }
  912. }
  913. /* queueLater */
  914. {
  915. fluid_evt_entry* tmp = seq->queueLater;
  916. fluid_evt_entry* prev = NULL;
  917. while (tmp) {
  918. if (_fluid_seq_queue_matchevent((&tmp->evt), type, src, dest)) {
  919. /* remove */
  920. if (prev) {
  921. prev->next = tmp->next;
  922. _fluid_seq_heap_set_free(seq->heap, tmp);
  923. tmp = prev->next;
  924. } else {
  925. seq->queueLater = tmp->next;
  926. _fluid_seq_heap_set_free(seq->heap, tmp);
  927. tmp = seq->queueLater;
  928. }
  929. } else {
  930. prev = tmp;
  931. tmp = prev->next;
  932. }
  933. }
  934. }
  935. }
  936. static void
  937. _fluid_seq_queue_send_cell_events(fluid_sequencer_t* seq, int cellNb)
  938. {
  939. fluid_evt_entry* next;
  940. fluid_evt_entry* tmp;
  941. tmp = seq->queue0[cellNb][0];
  942. while (tmp) {
  943. fluid_sequencer_send_now(seq, &(tmp->evt));
  944. next = tmp->next;
  945. _fluid_seq_heap_set_free(seq->heap, tmp);
  946. tmp = next;
  947. }
  948. seq->queue0[cellNb][0] = NULL;
  949. seq->queue0[cellNb][1] = NULL;
  950. }
  951. static void
  952. _fluid_seq_queue_slide(fluid_sequencer_t* seq)
  953. {
  954. short i;
  955. fluid_evt_entry* next;
  956. fluid_evt_entry* tmp;
  957. int count = 0;
  958. /* do the slide */
  959. seq->queue0StartTime += 256;
  960. /* sort all queue1[0] into queue0 according to new queue0StartTime */
  961. tmp = seq->queue1[0][0];
  962. while (tmp) {
  963. unsigned int delay = tmp->evt.time - seq->queue0StartTime;
  964. next = tmp->next;
  965. if (delay > 255) {
  966. /* should not happen !! */
  967. /* append it to queue1[1] */
  968. _fluid_seq_queue_insert_queue1(seq, tmp, 1);
  969. } else {
  970. _fluid_seq_queue_insert_queue0(seq, tmp, delay);
  971. }
  972. tmp = next;
  973. count++;
  974. }
  975. /* slide all queue1[i] into queue1[i-1] */
  976. for (i = 1 ; i < 255 ; i++) {
  977. seq->queue1[i-1][0] = seq->queue1[i][0];
  978. seq->queue1[i-1][1] = seq->queue1[i][1];
  979. }
  980. seq->queue1[254][0] = NULL;
  981. seq->queue1[254][1] = NULL;
  982. /* append queueLater to queue1[254] */
  983. count = 0;
  984. tmp = seq->queueLater;
  985. while (tmp) {
  986. unsigned int delay = tmp->evt.time - seq->queue0StartTime;
  987. if (delay > 65535) {
  988. break;
  989. }
  990. next = tmp->next;
  991. /* append it */
  992. _fluid_seq_queue_insert_queue1(seq, tmp, 254);
  993. tmp = next;
  994. count++;
  995. }
  996. seq->queueLater = tmp;
  997. }
  998. static void
  999. _fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq)
  1000. {
  1001. unsigned int nowTicks = fluid_sequencer_get_tick(seq);
  1002. short cellNb;
  1003. cellNb = seq->prevCellNb + 1;
  1004. while (cellNb <= (int)(nowTicks - seq->queue0StartTime)) {
  1005. if (cellNb == 256) {
  1006. cellNb = 0;
  1007. _fluid_seq_queue_slide(seq);
  1008. } /* slide */
  1009. /* process queue0[cellNb] */
  1010. _fluid_seq_queue_send_cell_events(seq, cellNb);
  1011. /* next cell */
  1012. cellNb++;
  1013. }
  1014. seq->prevCellNb = cellNb - 1;
  1015. }