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