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

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. #ifndef _FLUID_EVENT_QUEUE_H
  21. #define _FLUID_EVENT_QUEUE_H
  22. #include "fluid_sys.h"
  23. #include "fluid_midi.h"
  24. /**
  25.  * Type of queued event.
  26.  */
  27. enum fluid_event_queue_elem
  28. {
  29.   FLUID_EVENT_QUEUE_ELEM_MIDI,          /**< MIDI event. Uses midi field of event value */
  30.   FLUID_EVENT_QUEUE_ELEM_UPDATE_GAIN,   /**< Update synthesizer gain.  No payload value */
  31.   FLUID_EVENT_QUEUE_ELEM_POLYPHONY,     /**< Synth polyphony event. No payload value */
  32.   FLUID_EVENT_QUEUE_ELEM_GEN,           /**< Generator event. Uses gen field of event value */
  33.   FLUID_EVENT_QUEUE_ELEM_PRESET,        /**< Preset set event. Uses preset field of event value */
  34.   FLUID_EVENT_QUEUE_ELEM_STOP_VOICES,   /**< Stop voices event. Uses ival field of event value */
  35.   FLUID_EVENT_QUEUE_ELEM_FREE_PRESET,   /**< Free preset return event. Uses pval field of event value */
  36.   FLUID_EVENT_QUEUE_ELEM_SET_TUNING,    /**< Set tuning event. Uses set_tuning field of event value */
  37.   FLUID_EVENT_QUEUE_ELEM_REPL_TUNING,   /**< Replace tuning event. Uses repl_tuning field of event value */
  38.   FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING  /**< Unref tuning return event. Uses unref_tuning field of event value */
  39. };
  40. /**
  41.  * SoundFont generator set event structure.
  42.  */
  43. typedef struct
  44. {
  45.   int channel;          /**< MIDI channel number */
  46.   int param;            /**< FluidSynth generator ID */
  47.   float value;          /**< Value for the generator (absolute or relative) */
  48.   int absolute;         /**< 1 if value is absolute, 0 if relative */
  49. } fluid_event_gen_t;
  50. /**
  51.  * Preset channel assignment event structure.
  52.  */
  53. typedef struct
  54. {
  55.   int channel;                  /**< MIDI channel number */
  56.   fluid_preset_t *preset;       /**< Preset to assign (synth thread owns) */
  57. } fluid_event_preset_t;
  58. /**
  59.  * Tuning assignment event structure.
  60.  */
  61. typedef struct
  62. {
  63.   char apply;                   /**< TRUE to set tuning in realtime */
  64.   int channel;                  /**< MIDI channel number */
  65.   fluid_tuning_t *tuning;       /**< Tuning to assign */
  66. } fluid_event_set_tuning_t;
  67. /**
  68.  * Tuning replacement event structure.
  69.  */
  70. typedef struct
  71. {
  72.   char apply;                       /**< TRUE if tuning change should be applied in realtime */
  73.   fluid_tuning_t *old_tuning;       /**< Old tuning pointer to replace */
  74.   fluid_tuning_t *new_tuning;       /**< New tuning to assign */
  75. } fluid_event_repl_tuning_t;
  76. /**
  77.  * Tuning unref event structure.
  78.  */
  79. typedef struct
  80. {
  81.   fluid_tuning_t *tuning;           /**< Tuning to unref */
  82.   int count;                        /**< Number of times to unref */
  83. } fluid_event_unref_tuning_t;
  84. /**
  85.  * Structure for an integer parameter sent to a MIDI channel (bank or SoundFont ID for example).
  86.  */
  87. typedef struct
  88. {
  89.   int channel;
  90.   int val;
  91. } fluid_event_channel_int_t;
  92. /**
  93.  * Event queue element structure.
  94.  */
  95. typedef struct
  96. {
  97.   char type;            /**< fluid_event_queue_elem */
  98.   union
  99.   {
  100.     fluid_midi_event_t midi;    /**< If type == FLUID_EVENT_QUEUE_ELEM_MIDI */
  101.     fluid_event_gen_t gen;      /**< If type == FLUID_EVENT_QUEUE_ELEM_GEN */
  102.     fluid_event_preset_t preset;        /**< If type == FLUID_EVENT_QUEUE_ELEM_PRESET */
  103.     fluid_event_set_tuning_t set_tuning;        /**< If type == FLUID_EVENT_QUEUE_ELEM_SET_TUNING */
  104.     fluid_event_repl_tuning_t repl_tuning;      /**< If type == FLUID_EVENT_QUEUE_ELEM_REPL_TUNING */
  105.     fluid_event_unref_tuning_t unref_tuning;    /**< If type == FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING */
  106.     double dval;                /**< A floating point payload value */
  107.     int ival;                   /**< An integer payload value */
  108.     void *pval;                 /**< A pointer payload value */
  109.   };
  110. } fluid_event_queue_elem_t;
  111. /**
  112.  * Lockless event queue instance.
  113.  */
  114. typedef struct
  115. {
  116.   fluid_event_queue_elem_t *array;  /**< Queue array of arbitrary size elements */
  117.   int totalcount;       /**< Total count of elements in array */
  118.   int count;            /**< Current count of elements */
  119.   int in;               /**< Index in queue to store next pushed element */
  120.   int out;              /**< Index in queue of next popped element */
  121.   void *synth;          /**< Owning fluid_synth_t instance */
  122. } fluid_event_queue_t;
  123. fluid_event_queue_t *fluid_event_queue_new (int count);
  124. void fluid_event_queue_free (fluid_event_queue_t *queue);
  125. /**
  126.  * Get pointer to next input array element in queue.
  127.  * @param queue Lockless queue instance
  128.  * @return Pointer to array element in queue to store data to or NULL if queue is full
  129.  *
  130.  * This function along with fluid_queue_next_inptr() form a queue "push"
  131.  * operation and is split into 2 functions to avoid an element copy.  Note that
  132.  * the returned array element pointer may contain the data of a previous element
  133.  * if the queue has wrapped around.  This can be used to reclaim pointers to
  134.  * allocated memory, etc.
  135.  */
  136. static FLUID_INLINE fluid_event_queue_elem_t *
  137. fluid_event_queue_get_inptr (fluid_event_queue_t *queue)
  138. {
  139.   return fluid_atomic_int_get (&queue->count) == queue->totalcount ? NULL
  140.     : queue->array + queue->in;
  141. }
  142. /**
  143.  * Advance the input queue index to complete a "push" operation.
  144.  * @param queue Lockless queue instance
  145.  *
  146.  * This function along with fluid_queue_get_inptr() form a queue "push"
  147.  * operation and is split into 2 functions to avoid element copy.
  148.  */
  149. static FLUID_INLINE void
  150. fluid_event_queue_next_inptr (fluid_event_queue_t *queue)
  151. {
  152.   fluid_atomic_int_inc (&queue->count);
  153.   if (++queue->in == queue->totalcount)
  154.     queue->in = 0;
  155. }
  156. /**
  157.  * Get pointer to next output array element in queue.
  158.  * @param queue Lockless queue instance
  159.  * @return Pointer to array element data in the queue or NULL if empty, can only
  160.  *   be used up until fluid_queue_next_outptr() is called.
  161.  *
  162.  * This function along with fluid_queue_next_outptr() form a queue "pop"
  163.  * operation and is split into 2 functions to avoid an element copy.
  164.  */
  165. static FLUID_INLINE fluid_event_queue_elem_t *
  166. fluid_event_queue_get_outptr (fluid_event_queue_t *queue)
  167. {
  168.   return fluid_atomic_int_get (&queue->count) == 0 ? NULL
  169.     : queue->array + queue->out;
  170. }
  171. /**
  172.  * Advance the output queue index to complete a "pop" operation.
  173.  * @param queue Lockless queue instance
  174.  *
  175.  * This function along with fluid_queue_get_outptr() form a queue "pop"
  176.  * operation and is split into 2 functions to avoid an element copy.
  177.  */
  178. static FLUID_INLINE void
  179. fluid_event_queue_next_outptr (fluid_event_queue_t *queue)
  180. {
  181.   fluid_atomic_int_add (&queue->count, -1);
  182.   if (++queue->out == queue->totalcount)
  183.     queue->out = 0;
  184. }
  185. #endif /* _FLUID_EVENT_QUEUE_H */