1d5ac70f0Sopenharmony_ci/**
2d5ac70f0Sopenharmony_ci * \file seq/seq.c
3d5ac70f0Sopenharmony_ci * \brief Sequencer Interface
4d5ac70f0Sopenharmony_ci * \author Jaroslav Kysela <perex@perex.cz>
5d5ac70f0Sopenharmony_ci * \author Abramo Bagnara <abramo@alsa-project.org>
6d5ac70f0Sopenharmony_ci * \author Takashi Iwai <tiwai@suse.de>
7d5ac70f0Sopenharmony_ci * \date 2000-2001
8d5ac70f0Sopenharmony_ci *
9d5ac70f0Sopenharmony_ci * See \ref seq page for more details.
10d5ac70f0Sopenharmony_ci */
11d5ac70f0Sopenharmony_ci
12d5ac70f0Sopenharmony_ci/*
13d5ac70f0Sopenharmony_ci *  Sequencer Interface - main file
14d5ac70f0Sopenharmony_ci *
15d5ac70f0Sopenharmony_ci *   This library is free software; you can redistribute it and/or modify
16d5ac70f0Sopenharmony_ci *   it under the terms of the GNU Lesser General Public License as
17d5ac70f0Sopenharmony_ci *   published by the Free Software Foundation; either version 2.1 of
18d5ac70f0Sopenharmony_ci *   the License, or (at your option) any later version.
19d5ac70f0Sopenharmony_ci *
20d5ac70f0Sopenharmony_ci *   This program is distributed in the hope that it will be useful,
21d5ac70f0Sopenharmony_ci *   but WITHOUT ANY WARRANTY; without even the implied warranty of
22d5ac70f0Sopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23d5ac70f0Sopenharmony_ci *   GNU Lesser General Public License for more details.
24d5ac70f0Sopenharmony_ci *
25d5ac70f0Sopenharmony_ci *   You should have received a copy of the GNU Lesser General Public
26d5ac70f0Sopenharmony_ci *   License along with this library; if not, write to the Free Software
27d5ac70f0Sopenharmony_ci *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28d5ac70f0Sopenharmony_ci *
29d5ac70f0Sopenharmony_ci */
30d5ac70f0Sopenharmony_ci
31d5ac70f0Sopenharmony_ci/*! \page seq Sequencer interface
32d5ac70f0Sopenharmony_ci
33d5ac70f0Sopenharmony_ci\section seq_general General
34d5ac70f0Sopenharmony_ci
35d5ac70f0Sopenharmony_ciThe ALSA sequencer interface is designed to deliver the MIDI-like
36d5ac70f0Sopenharmony_cievents between clients/ports.
37d5ac70f0Sopenharmony_ciA typical usage is the MIDI patch-bay.  A MIDI application can be
38d5ac70f0Sopenharmony_ciconnected arbitrarily from/to the other MIDI clients.
39d5ac70f0Sopenharmony_ciThe routing between clients can be changed dynamically, so the
40d5ac70f0Sopenharmony_ciapplication can handle incoming or outgoing MIDI events regardless of
41d5ac70f0Sopenharmony_cithe devices or the application connections.
42d5ac70f0Sopenharmony_ci
43d5ac70f0Sopenharmony_ciThe sequencer core stuff only takes care of two things:
44d5ac70f0Sopenharmony_cischeduling events and dispatching them to the destination at the
45d5ac70f0Sopenharmony_ciright time.  All processing of MIDI events has to be done within the clients.
46d5ac70f0Sopenharmony_ciThe event can be dispatched immediately without queueing, too.
47d5ac70f0Sopenharmony_ciThe event scheduling can be done either on a MIDI tempo queue or
48d5ac70f0Sopenharmony_cion a wallclock-time queue.
49d5ac70f0Sopenharmony_ci
50d5ac70f0Sopenharmony_ci\section seq_client Client and Port
51d5ac70f0Sopenharmony_ci
52d5ac70f0Sopenharmony_ciA <i>client</i> is created at each time #snd_seq_open() is called.
53d5ac70f0Sopenharmony_ciLater on, the attributes of client such as its name string can be changed
54d5ac70f0Sopenharmony_civia #snd_seq_set_client_info().  There are helper functions for ease of use,
55d5ac70f0Sopenharmony_cie.g. #snd_seq_set_client_name() and #snd_seq_set_client_event_filter().
56d5ac70f0Sopenharmony_ciA typical code would be like below:
57d5ac70f0Sopenharmony_ci\code
58d5ac70f0Sopenharmony_ci// create a new client
59d5ac70f0Sopenharmony_cisnd_seq_t *open_client()
60d5ac70f0Sopenharmony_ci{
61d5ac70f0Sopenharmony_ci        snd_seq_t *handle;
62d5ac70f0Sopenharmony_ci        int err;
63d5ac70f0Sopenharmony_ci        err = snd_seq_open(&handle, "default", SND_SEQ_OPEN_INPUT, 0);
64d5ac70f0Sopenharmony_ci        if (err < 0)
65d5ac70f0Sopenharmony_ci                return NULL;
66d5ac70f0Sopenharmony_ci        snd_seq_set_client_name(handle, "My Client");
67d5ac70f0Sopenharmony_ci	return handle;
68d5ac70f0Sopenharmony_ci}
69d5ac70f0Sopenharmony_ci\endcode
70d5ac70f0Sopenharmony_ci
71d5ac70f0Sopenharmony_ciYou'll need to know the id number of the client eventually, for example,
72d5ac70f0Sopenharmony_ciwhen accessing to a certain port (see the section \ref seq_subs).
73d5ac70f0Sopenharmony_ciThe client id can be obtained by #snd_seq_client_id() function.
74d5ac70f0Sopenharmony_ci
75d5ac70f0Sopenharmony_ciA client can have one or more <i>ports</i> to communicate between other
76d5ac70f0Sopenharmony_ciclients.  A port is corresponding to the MIDI port in the case of MIDI device,
77d5ac70f0Sopenharmony_cibut in general it is nothing but the access point between other clients.
78d5ac70f0Sopenharmony_ciEach port may have capability flags, which specify the read/write
79d5ac70f0Sopenharmony_ciaccessibility and subscription permissions of the port.
80d5ac70f0Sopenharmony_ciFor creation of a port, call #snd_seq_create_port()
81d5ac70f0Sopenharmony_ciwith the appropriate port attribute specified in #snd_seq_port_info_t
82d5ac70f0Sopenharmony_cirecord.
83d5ac70f0Sopenharmony_ci
84d5ac70f0Sopenharmony_ciFor creating a port for the normal use, there is a helper function
85d5ac70f0Sopenharmony_ci#snd_seq_create_simple_port().  An example with this function is like below.
86d5ac70f0Sopenharmony_ci\code
87d5ac70f0Sopenharmony_ci// create a new port; return the port id
88d5ac70f0Sopenharmony_ci// port will be writable and accept the write-subscription.
89d5ac70f0Sopenharmony_ciint my_new_port(snd_seq_t *handle)
90d5ac70f0Sopenharmony_ci{
91d5ac70f0Sopenharmony_ci	return snd_seq_create_simple_port(handle, "my port",
92d5ac70f0Sopenharmony_ci			SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
93d5ac70f0Sopenharmony_ci			SND_SEQ_PORT_TYPE_MIDI_GENERIC);
94d5ac70f0Sopenharmony_ci}
95d5ac70f0Sopenharmony_ci\endcode
96d5ac70f0Sopenharmony_ci
97d5ac70f0Sopenharmony_ci\section seq_memory Memory Pool
98d5ac70f0Sopenharmony_ci
99d5ac70f0Sopenharmony_ciEach client owns memory pools on kernel space
100d5ac70f0Sopenharmony_cifor each input and output events.
101d5ac70f0Sopenharmony_ciHere, input and output mean
102d5ac70f0Sopenharmony_ciinput (read) from other clients and output (write) to others, respectively.
103d5ac70f0Sopenharmony_ciSince memory pool of each client is independent from others,
104d5ac70f0Sopenharmony_ciit avoids such a situation that a client eats the whole events pool
105d5ac70f0Sopenharmony_ciand interfere other clients' response.
106d5ac70f0Sopenharmony_ci
107d5ac70f0Sopenharmony_ciThe all scheduled output events or input events from dispatcher are stored
108d5ac70f0Sopenharmony_cion these pools until delivered to other clients or extracted to user space.
109d5ac70f0Sopenharmony_ciThe size of input/output pools can be changed independently.
110d5ac70f0Sopenharmony_ciThe output pool has also a room size, which is used to wake up the
111d5ac70f0Sopenharmony_cithread when it falls into sleep in blocking write mode.
112d5ac70f0Sopenharmony_ci
113d5ac70f0Sopenharmony_ciNote that ports on the same client share the same memory pool.
114d5ac70f0Sopenharmony_ciIf a port fills the memory pool, another can't use it any more.
115d5ac70f0Sopenharmony_ciFor avoiding this, multiple clients can be used.
116d5ac70f0Sopenharmony_ci
117d5ac70f0Sopenharmony_ciFor chancing the pool size and the condition, access to #snd_seq_client_pool_t
118d5ac70f0Sopenharmony_cirecord.  There are helper functions, #snd_seq_set_client_pool_output(),
119d5ac70f0Sopenharmony_ci#snd_seq_set_client_pool_output_room() and #snd_seq_set_client_pool_input(),
120d5ac70f0Sopenharmony_cifor setting the total output-pool size, the output-room size and the input-pool
121d5ac70f0Sopenharmony_cisize, respectively.
122d5ac70f0Sopenharmony_ci
123d5ac70f0Sopenharmony_ci\section seq_subs Subscription
124d5ac70f0Sopenharmony_ci
125d5ac70f0Sopenharmony_ciOne of the new features in ALSA sequencer system is <i>subscription</i> of ports.
126d5ac70f0Sopenharmony_ciIn general, subscription is a connection between two sequencer ports.
127d5ac70f0Sopenharmony_ciEven though an event can be delivered to a port without subscription
128d5ac70f0Sopenharmony_ciusing an explicit destination address,
129d5ac70f0Sopenharmony_cithe subscription mechanism provides us more abstraction.
130d5ac70f0Sopenharmony_ci
131d5ac70f0Sopenharmony_ciSuppose a MIDI input device which sends events from a keyboard.
132d5ac70f0Sopenharmony_ciThe port associated with this device has READ capability - which means
133d5ac70f0Sopenharmony_cithis port is readable from other ports.
134d5ac70f0Sopenharmony_ciIf a user program wants to capture events from keyboard and store them
135d5ac70f0Sopenharmony_cias MIDI stream, this program must subscribe itself to the MIDI port
136d5ac70f0Sopenharmony_cifor read.
137d5ac70f0Sopenharmony_ciThen, a connection from MIDI input port to this program is established.
138d5ac70f0Sopenharmony_ciFrom this time, events from keyboard are automatically sent to this program.
139d5ac70f0Sopenharmony_ciTimestamps will be updated according to the subscribed queue.
140d5ac70f0Sopenharmony_ci\code
141d5ac70f0Sopenharmony_ci        MIDI input port (keyboard)
142d5ac70f0Sopenharmony_ci            |
143d5ac70f0Sopenharmony_ci            V
144d5ac70f0Sopenharmony_ci        ALSA sequencer - update timestamp
145d5ac70f0Sopenharmony_ci            |
146d5ac70f0Sopenharmony_ci            V
147d5ac70f0Sopenharmony_ci        application port
148d5ac70f0Sopenharmony_ci\endcode
149d5ac70f0Sopenharmony_ci
150d5ac70f0Sopenharmony_ciThere is another subscription type for opposite direction:
151d5ac70f0Sopenharmony_ciSuppose a MIDI sequencer program which sends events to a MIDI output device.
152d5ac70f0Sopenharmony_ciIn ALSA system, MIDI device is not opened until the associated MIDI port
153d5ac70f0Sopenharmony_ciis accessed.  Thus, in order to activate MIDI device, we have to subscribe
154d5ac70f0Sopenharmony_cito MIDI port for write.
155d5ac70f0Sopenharmony_ciAfter this connection is established, events will be properly sent
156d5ac70f0Sopenharmony_cito MIDI output device.
157d5ac70f0Sopenharmony_ci\code
158d5ac70f0Sopenharmony_ci        application port
159d5ac70f0Sopenharmony_ci            |
160d5ac70f0Sopenharmony_ci            V
161d5ac70f0Sopenharmony_ci        ALSA sequencer - events are scheduled
162d5ac70f0Sopenharmony_ci            |
163d5ac70f0Sopenharmony_ci            V
164d5ac70f0Sopenharmony_ci        MIDI output port (WaveTable etc.)
165d5ac70f0Sopenharmony_ci\endcode
166d5ac70f0Sopenharmony_ci
167d5ac70f0Sopenharmony_ciFrom the viewpoint of subscription, the examples above are special cases.
168d5ac70f0Sopenharmony_ciBasically, subscription means the connection between two arbitrary ports.
169d5ac70f0Sopenharmony_ciFor example, imagine a filter application which modifies
170d5ac70f0Sopenharmony_cithe MIDI events like program, velocity or chorus effects.
171d5ac70f0Sopenharmony_ciThis application can accept arbitrary MIDI input
172d5ac70f0Sopenharmony_ciand send to arbitrary port, just like a Unix pipe application using
173d5ac70f0Sopenharmony_cistdin and stdout files.
174d5ac70f0Sopenharmony_ciWe can even connect several filter applications which work individually
175d5ac70f0Sopenharmony_ciin order to process the MIDI events.
176d5ac70f0Sopenharmony_ciSubscription can be used for this purpose.
177d5ac70f0Sopenharmony_ciThe connection between ports can be done also by the "third" client.
178d5ac70f0Sopenharmony_ciThus, filter applications have to manage
179d5ac70f0Sopenharmony_cionly input and output events regardless of receiver/sender addresses.
180d5ac70f0Sopenharmony_ci\code
181d5ac70f0Sopenharmony_ci        sequencer port #1
182d5ac70f0Sopenharmony_ci            |
183d5ac70f0Sopenharmony_ci            V
184d5ac70f0Sopenharmony_ci        ALSA sequencer (scheduled or real-time)
185d5ac70f0Sopenharmony_ci            |
186d5ac70f0Sopenharmony_ci            V
187d5ac70f0Sopenharmony_ci        sequencer port #2
188d5ac70f0Sopenharmony_ci\endcode
189d5ac70f0Sopenharmony_ci
190d5ac70f0Sopenharmony_ciFor the detail about subscription, see the section \ref seq_subs_more.
191d5ac70f0Sopenharmony_ci
192d5ac70f0Sopenharmony_ci\section seq_events Sequencer Events
193d5ac70f0Sopenharmony_ci
194d5ac70f0Sopenharmony_ciMessaging between clients is performed by sending events from one client to
195d5ac70f0Sopenharmony_cianother. These events contain high-level MIDI oriented messages or sequencer
196d5ac70f0Sopenharmony_cispecific messages.
197d5ac70f0Sopenharmony_ci
198d5ac70f0Sopenharmony_ciAll the sequencer events are stored in a sequencer event record,
199d5ac70f0Sopenharmony_ci#snd_seq_event_t type.
200d5ac70f0Sopenharmony_ciApplication can send and receive these event records to/from other
201d5ac70f0Sopenharmony_ciclients via sequencer.
202d5ac70f0Sopenharmony_ciAn event has several storage types according to its usage.
203d5ac70f0Sopenharmony_ciFor example, a SYSEX message is stored on the variable length event,
204d5ac70f0Sopenharmony_ciand a large synth sample data is delivered using a user-space data pointer.
205d5ac70f0Sopenharmony_ci
206d5ac70f0Sopenharmony_ci
207d5ac70f0Sopenharmony_ci\subsection seq_ev_struct Structure of an event
208d5ac70f0Sopenharmony_ci
209d5ac70f0Sopenharmony_ciAn event consists of the following items:
210d5ac70f0Sopenharmony_ci<ul>
211d5ac70f0Sopenharmony_ci<li>The type of the event
212d5ac70f0Sopenharmony_ci<li>Event flags.  It describes various conditions:
213d5ac70f0Sopenharmony_ci  <ul>
214d5ac70f0Sopenharmony_ci  <li>time stamp; "real time" / "song ticks"
215d5ac70f0Sopenharmony_ci  <li>time mode; "absolute" / "relative to current time"
216d5ac70f0Sopenharmony_ci  </ul>
217d5ac70f0Sopenharmony_ci<li>Timestamp of the event.
218d5ac70f0Sopenharmony_ci<li>Scheduling queue id.
219d5ac70f0Sopenharmony_ci<li>Source address of the event, given by the combination
220d5ac70f0Sopenharmony_ci  of client id and port id numbers.
221d5ac70f0Sopenharmony_ci<li>Destination address of the event.
222d5ac70f0Sopenharmony_ci<li>The actual event data. (up to 12 bytes)
223d5ac70f0Sopenharmony_ci</ul>
224d5ac70f0Sopenharmony_ci
225d5ac70f0Sopenharmony_ciThe actual record is shown in #snd_seq_event_t.
226d5ac70f0Sopenharmony_ciThe type field contains the type of the event
227d5ac70f0Sopenharmony_ci(1 byte).
228d5ac70f0Sopenharmony_ciThe flags field consists of bit flags which
229d5ac70f0Sopenharmony_cidescribe several conditions of the event (1 byte).
230d5ac70f0Sopenharmony_ciIt includes the time-stamp mode, data storage type, and scheduling priority.
231d5ac70f0Sopenharmony_ciThe tag field is an arbitrary tag.
232d5ac70f0Sopenharmony_ciThis tag can used for removing a distinct event from the event queue
233d5ac70f0Sopenharmony_civia #snd_seq_remove_events().
234d5ac70f0Sopenharmony_ciThe queue field is the queue id for scheduling.
235d5ac70f0Sopenharmony_ciThe source and dest fields are source and destination addresses.
236d5ac70f0Sopenharmony_ciThe data field is a union of event data.
237d5ac70f0Sopenharmony_ci
238d5ac70f0Sopenharmony_ci\subsection seq_ev_queue Scheduling queue
239d5ac70f0Sopenharmony_ci
240d5ac70f0Sopenharmony_ciAn event can be delivered either on scheduled or direct dispatch mode.
241d5ac70f0Sopenharmony_ciOn the scheduling mode, an event is once stored on the priority queue
242d5ac70f0Sopenharmony_ciand delivered later (or even immediately) to the destination,
243d5ac70f0Sopenharmony_ciwhereas on the direct dispatch mode, an event is passed to the destination
244d5ac70f0Sopenharmony_ciwithout any queue.
245d5ac70f0Sopenharmony_ci
246d5ac70f0Sopenharmony_ciFor a scheduled delivery, a queue to process the event must exist.
247d5ac70f0Sopenharmony_ciUsually, a client creates its own queue by
248d5ac70f0Sopenharmony_ci#snd_seq_alloc_queue() function.
249d5ac70f0Sopenharmony_ciAlternatively, a queue may be shared among several clients.
250d5ac70f0Sopenharmony_ciFor scheduling an event on the specified queue,
251d5ac70f0Sopenharmony_cia client needs to fill queue field
252d5ac70f0Sopenharmony_ciwith the preferred queue id.
253d5ac70f0Sopenharmony_ci
254d5ac70f0Sopenharmony_ciMeanwhile, for dispatching an event directly, just
255d5ac70f0Sopenharmony_ciuse #SND_SEQ_QUEUE_DIRECT as the target queue id.
256d5ac70f0Sopenharmony_ciA macro #snd_seq_ev_set_direct() is provided for ease
257d5ac70f0Sopenharmony_ciand compatibility.
258d5ac70f0Sopenharmony_ci
259d5ac70f0Sopenharmony_ciNote that scheduling at the current or earlier time is different
260d5ac70f0Sopenharmony_cifrom the direct dispatch mode even though the event is delivered immediately.
261d5ac70f0Sopenharmony_ciOn the former scheme, an event is once stored on priority queue, then
262d5ac70f0Sopenharmony_cidelivered actually.  Thus, it acquires a space from memory pool.
263d5ac70f0Sopenharmony_ciOn the other hand, the latter is passed without using memory pool.
264d5ac70f0Sopenharmony_ciAlthough the direct dispatched event needs less memory, it means also
265d5ac70f0Sopenharmony_cithat the event cannot be resent if the destination is unable to receive it
266d5ac70f0Sopenharmony_cimomentarily.
267d5ac70f0Sopenharmony_ci
268d5ac70f0Sopenharmony_ci\subsection seq_ev_time Time stamp
269d5ac70f0Sopenharmony_ci
270d5ac70f0Sopenharmony_ciThe timestamp of the event can either specified in
271d5ac70f0Sopenharmony_ci<i>real time</i> or in <i>song ticks</i>.
272d5ac70f0Sopenharmony_ciThe former means the wallclock time while the latter corresponds to
273d5ac70f0Sopenharmony_cithe MIDI ticks.
274d5ac70f0Sopenharmony_ciWhich format is used is determined by the event flags.
275d5ac70f0Sopenharmony_ci
276d5ac70f0Sopenharmony_ciThe resolution of real-time value is in nano second.
277d5ac70f0Sopenharmony_ciSince 64 bit length is required for the actual time calculation,
278d5ac70f0Sopenharmony_ciit is represented by
279d5ac70f0Sopenharmony_cia structure of pair of second and nano second
280d5ac70f0Sopenharmony_cidefined as #snd_seq_real_time_t type.
281d5ac70f0Sopenharmony_ciThe song tick is defined simply as a 32 bit integer,
282d5ac70f0Sopenharmony_cidefined as #snd_seq_tick_time_t type.
283d5ac70f0Sopenharmony_ciThe time stored in an event record is a union of these two different
284d5ac70f0Sopenharmony_citime values.
285d5ac70f0Sopenharmony_ci
286d5ac70f0Sopenharmony_ciNote that the time format used for real time events is very similar to
287d5ac70f0Sopenharmony_citimeval struct used for Unix system time.
288d5ac70f0Sopenharmony_ciThe absurd resolution of the timestamps allows us to perform very accurate
289d5ac70f0Sopenharmony_ciconversions between songposition and real time. Round-off errors can be
290d5ac70f0Sopenharmony_cineglected.
291d5ac70f0Sopenharmony_ci
292d5ac70f0Sopenharmony_ciIf a timestamp with a
293d5ac70f0Sopenharmony_ci<i>relative</i> timestamp is delivered to ALSA, the
294d5ac70f0Sopenharmony_cispecified timestamp will be used as an offset to the current time of the
295d5ac70f0Sopenharmony_ciqueue the event is sent into.
296d5ac70f0Sopenharmony_ciAn <i>absolute</i> timestamp is on the contrary the time
297d5ac70f0Sopenharmony_cicounted from the moment when the queue started.
298d5ac70f0Sopenharmony_ci
299d5ac70f0Sopenharmony_ciAn client that relies on these relative timestamps is the MIDI input port.
300d5ac70f0Sopenharmony_ciAs each sequencer queue has it's own clock the only way to deliver events at
301d5ac70f0Sopenharmony_cithe right time is by using the relative timestamp format. When the event
302d5ac70f0Sopenharmony_ciarrives at the queue it is normalized to absolute format.
303d5ac70f0Sopenharmony_ci
304d5ac70f0Sopenharmony_ciThe timestamp format is specified in the flag bitfield masked by
305d5ac70f0Sopenharmony_ci#SND_SEQ_TIME_STAMP_MASK.
306d5ac70f0Sopenharmony_ciTo schedule the event in a real-time queue or in a tick queue,
307d5ac70f0Sopenharmony_cimacros #snd_seq_ev_schedule_real() and
308d5ac70f0Sopenharmony_ci#snd_seq_ev_schedule_tick() are provided, respectively.
309d5ac70f0Sopenharmony_ci
310d5ac70f0Sopenharmony_ci\subsection seq_ev_addr Source and destination addresses
311d5ac70f0Sopenharmony_ci
312d5ac70f0Sopenharmony_ciTo identify the source and destination of an event, the addressing field
313d5ac70f0Sopenharmony_cicontains a combination of client id and port id numbers, defined as
314d5ac70f0Sopenharmony_ci#snd_seq_addr_t type.
315d5ac70f0Sopenharmony_ciWhen an event is passed to sequencer from a client, sequencer fills
316d5ac70f0Sopenharmony_cisource.client field
317d5ac70f0Sopenharmony_ciwith the sender's id automatically.
318d5ac70f0Sopenharmony_ciIt is the responsibility of sender client to
319d5ac70f0Sopenharmony_cifill the port id of source.port and
320d5ac70f0Sopenharmony_ciboth client and port of dest field.
321d5ac70f0Sopenharmony_ci
322d5ac70f0Sopenharmony_ciIf an existing address is set to the destination,
323d5ac70f0Sopenharmony_cithe event is simply delivered to it.
324d5ac70f0Sopenharmony_ciWhen #SND_SEQ_ADDRESS_SUBSCRIBERS is set to the destination client id,
325d5ac70f0Sopenharmony_cithe event is delivered to all the clients connected to the source port.
326d5ac70f0Sopenharmony_ci
327d5ac70f0Sopenharmony_ci
328d5ac70f0Sopenharmony_ciA sequencer core has two pre-defined system ports on the system client
329d5ac70f0Sopenharmony_ci#SND_SEQ_CLIENT_SYSTEM: #SND_SEQ_PORT_SYSTEM_TIMER and #SND_SEQ_PORT_SYSTEM_ANNOUNCE.
330d5ac70f0Sopenharmony_ciThe #SND_SEQ_PORT_SYSTEM_TIMER is the system timer port,
331d5ac70f0Sopenharmony_ciand #SND_SEQ_PORT_SYSTEM_ANNOUNCE is the system
332d5ac70f0Sopenharmony_ciannounce port.
333d5ac70f0Sopenharmony_ciIn order to control a queue from a client, client should send a
334d5ac70f0Sopenharmony_ciqueue-control event
335d5ac70f0Sopenharmony_cilike start, stop and continue queue, change tempo, etc.
336d5ac70f0Sopenharmony_cito the system timer port.
337d5ac70f0Sopenharmony_ciThen the sequencer system handles the queue according to the received event.
338d5ac70f0Sopenharmony_ciThis port supports subscription. The received timer events are
339d5ac70f0Sopenharmony_cibroadcasted to all subscribed clients.
340d5ac70f0Sopenharmony_ci
341d5ac70f0Sopenharmony_ciThe latter port does not receive messages but supports subscription.
342d5ac70f0Sopenharmony_ciWhen each client or port is attached, detached or modified,
343d5ac70f0Sopenharmony_cian announcement is sent to subscribers from this port.
344d5ac70f0Sopenharmony_ci
345d5ac70f0Sopenharmony_ci\subsection seq_ev_data Data storage type
346d5ac70f0Sopenharmony_ci
347d5ac70f0Sopenharmony_ciSome events like SYSEX message, however, need larger data space
348d5ac70f0Sopenharmony_cithan the standard data.
349d5ac70f0Sopenharmony_ciFor such events, ALSA sequencer provides several different data storage types.
350d5ac70f0Sopenharmony_ciThe data type is specified in the flag bits masked by #SND_SEQ_EVENT_LENGTH_MASK.
351d5ac70f0Sopenharmony_ciThe following data types are available:
352d5ac70f0Sopenharmony_ci
353d5ac70f0Sopenharmony_ci\par Fixed size data
354d5ac70f0Sopenharmony_ciNormal events stores their parameters on
355d5ac70f0Sopenharmony_cidata field (12 byte).
356d5ac70f0Sopenharmony_ciThe flag-bit type is  #SND_SEQ_EVENT_LENGTH_FIXED.
357d5ac70f0Sopenharmony_ciA macro #snd_seq_ev_set_fixed() is provided to set this type.
358d5ac70f0Sopenharmony_ci
359d5ac70f0Sopenharmony_ci\par Variable length data
360d5ac70f0Sopenharmony_ciSYSEX or a returned error use this type.
361d5ac70f0Sopenharmony_ciThe actual data is stored on an extra allocated space.
362d5ac70f0Sopenharmony_ciOn sequencer kernel, the whole extra-data is duplicated, so that the event
363d5ac70f0Sopenharmony_cican be scheduled on queue.
364d5ac70f0Sopenharmony_ciThe data contains only the length and the
365d5ac70f0Sopenharmony_cipointer of extra-data.
366d5ac70f0Sopenharmony_ciThe flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARIABLE.
367d5ac70f0Sopenharmony_ciA macro #snd_seq_ev_set_variable() is provided to set this type.
368d5ac70f0Sopenharmony_ci
369d5ac70f0Sopenharmony_ci\par User-space data
370d5ac70f0Sopenharmony_ciThis type refers also an extra data space like variable length data,
371d5ac70f0Sopenharmony_cibut the extra-data is not duplicated but
372d5ac70f0Sopenharmony_cibut referred as a user-space data on kernel,
373d5ac70f0Sopenharmony_ciso that it reduces the time and resource for transferring
374d5ac70f0Sopenharmony_cilarge bulk of data like synth sample wave.
375d5ac70f0Sopenharmony_ciThis data type, however, can be used only for direct dispatch mode,
376d5ac70f0Sopenharmony_ciand supposed to be used only for a special purpose like a bulk data
377d5ac70f0Sopenharmony_citransfer.
378d5ac70f0Sopenharmony_ciThe data length and pointer are stored also in
379d5ac70f0Sopenharmony_cidata.ext field as well as variable length data.
380d5ac70f0Sopenharmony_ciThe flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARUSR.
381d5ac70f0Sopenharmony_ciA macro #snd_seq_ev_set_varusr() is provided to set this type.
382d5ac70f0Sopenharmony_ci
383d5ac70f0Sopenharmony_ci\subsection seq_ev_sched Scheduling priority
384d5ac70f0Sopenharmony_ci
385d5ac70f0Sopenharmony_ciThere are two priorities for scheduling:
386d5ac70f0Sopenharmony_ci\par Normal priority
387d5ac70f0Sopenharmony_ciIf an event with the same scheduling time is already present on the queue,
388d5ac70f0Sopenharmony_cithe new event is appended to the older.
389d5ac70f0Sopenharmony_ci\par High priority
390d5ac70f0Sopenharmony_ciIf an event with the same scheduling time is already present on the queue,
391d5ac70f0Sopenharmony_cithe new event is inserted before others.
392d5ac70f0Sopenharmony_ci
393d5ac70f0Sopenharmony_ciThe scheduling priority is set in the flag bitfeld masked by #SND_SEQ_PRIORITY_MASK.
394d5ac70f0Sopenharmony_ciA macro #snd_seq_ev_set_priority() is provided to set the mode type.
395d5ac70f0Sopenharmony_ci
396d5ac70f0Sopenharmony_ci\section seq_queue Event Queues
397d5ac70f0Sopenharmony_ci\subsection seq_ev_control Creation of a queue
398d5ac70f0Sopenharmony_ci
399d5ac70f0Sopenharmony_ciCreating a queue is done usually by calling #snd_seq_alloc_queue.
400d5ac70f0Sopenharmony_ciYou can create a queue with a certain name by #snd_seq_alloc_named_queue(), too.
401d5ac70f0Sopenharmony_ci\code
402d5ac70f0Sopenharmony_ci// create a queue and return its id
403d5ac70f0Sopenharmony_ciint my_queue(snd_seq_t *handle)
404d5ac70f0Sopenharmony_ci{
405d5ac70f0Sopenharmony_ci	return snd_seq_alloc_named_queue(handle, "my queue");
406d5ac70f0Sopenharmony_ci}
407d5ac70f0Sopenharmony_ci\endcode
408d5ac70f0Sopenharmony_ciThese functions are the wrapper to the function #snd_seq_create_queue().
409d5ac70f0Sopenharmony_ciFor releasing the allocated queue, call #snd_seq_free_queue() with the
410d5ac70f0Sopenharmony_ciobtained queue id.
411d5ac70f0Sopenharmony_ci
412d5ac70f0Sopenharmony_ciOnce when a queue is created, the two queues are associated to that
413d5ac70f0Sopenharmony_ciqueue record in fact: one is the realtime queue and another is the
414d5ac70f0Sopenharmony_citick queue.  These two queues are bound together to work
415d5ac70f0Sopenharmony_cisynchronously.  Hence, when you schedule an event, you have to choose
416d5ac70f0Sopenharmony_ciwhich queue type is used as described in the section \ref
417d5ac70f0Sopenharmony_ciseq_ev_time.
418d5ac70f0Sopenharmony_ci
419d5ac70f0Sopenharmony_ci\subsection seq_ev_tempo Setting queue tempo
420d5ac70f0Sopenharmony_ci
421d5ac70f0Sopenharmony_ciThe tempo (or the speed) of the scheduling queue is variable.
422d5ac70f0Sopenharmony_ciIn the case of <i>tick</i> queue, the tempo is controlled
423d5ac70f0Sopenharmony_ciin the manner of MIDI.  There are two parameters to define the
424d5ac70f0Sopenharmony_ciactual tempo, PPQ (pulse per quarter note) and MIDI tempo.
425d5ac70f0Sopenharmony_ciThe former defines the base resolution of the ticks, while
426d5ac70f0Sopenharmony_cithe latter defines the beat tempo in microseconds.
427d5ac70f0Sopenharmony_ciAs default, 96 PPQ and 120 BPM are used, respectively.
428d5ac70f0Sopenharmony_ciThat is, the tempo is set to 500000 (= 60 * 1000000 / 120).
429d5ac70f0Sopenharmony_ciNote that PPQ cannot be changed while the queue is running.
430d5ac70f0Sopenharmony_ciIt must be set before the queue is started.
431d5ac70f0Sopenharmony_ci
432d5ac70f0Sopenharmony_ciOn the other hand, in the case of <i>realtime</i> queue, the
433d5ac70f0Sopenharmony_citime resolution is fixed to nanoseconds.  There is, however,
434d5ac70f0Sopenharmony_cia parameter to change the speed of this queue, called <i>skew</i>.
435d5ac70f0Sopenharmony_ciYou can make the queue faster or slower by setting the skew value
436d5ac70f0Sopenharmony_cibigger or smaller.  In the API, the skew is defined by two values,
437d5ac70f0Sopenharmony_cithe skew base and the skew value.  The actual skew is the fraction
438d5ac70f0Sopenharmony_ciof them, <i>value/base</i>.  As default, the skew base is set to 16bit
439d5ac70f0Sopenharmony_ci(0x10000) and the skew value is the identical, so that the queue is
440d5ac70f0Sopenharmony_ciprocessed as well as in the real world.
441d5ac70f0Sopenharmony_ci
442d5ac70f0Sopenharmony_ciWhen the tempo of realtime queue is changed, the tempo of
443d5ac70f0Sopenharmony_cithe associated tick queue is changed together, too.
444d5ac70f0Sopenharmony_ciThat's the reason why two queues are created always.
445d5ac70f0Sopenharmony_ciThis feature can be used to synchronize the event queue with
446d5ac70f0Sopenharmony_cithe external synchronization source like SMPTE.  In such a case,
447d5ac70f0Sopenharmony_cithe realtime queue is skewed to match with the external source,
448d5ac70f0Sopenharmony_ciso that both the realtime timestamp and the MIDI timestamp are
449d5ac70f0Sopenharmony_cisynchronized.
450d5ac70f0Sopenharmony_ci
451d5ac70f0Sopenharmony_ciFor setting these tempo parameters, use #snd_seq_queue_tempo_t record.
452d5ac70f0Sopenharmony_ciFor example, to set the tempo of the queue <code>q</code> to
453d5ac70f0Sopenharmony_ci48 PPQ, 60 BPM,
454d5ac70f0Sopenharmony_ci\code
455d5ac70f0Sopenharmony_civoid set_tempo(snd_seq_t *handle, int queue)
456d5ac70f0Sopenharmony_ci{
457d5ac70f0Sopenharmony_ci        snd_seq_queue_tempo_t *tempo;
458d5ac70f0Sopenharmony_ci        snd_seq_queue_tempo_alloca(&tempo);
459d5ac70f0Sopenharmony_ci        snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM
460d5ac70f0Sopenharmony_ci        snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ
461d5ac70f0Sopenharmony_ci        snd_seq_set_queue_tempo(handle, queue, tempo);
462d5ac70f0Sopenharmony_ci}
463d5ac70f0Sopenharmony_ci\endcode
464d5ac70f0Sopenharmony_ci
465d5ac70f0Sopenharmony_ciFor changing the (running) queue's tempo on the fly, you can either
466d5ac70f0Sopenharmony_ciset the tempo via #snd_seq_set_queue_tempo() or send a MIDI tempo event
467d5ac70f0Sopenharmony_cito the system timer port.  For example,
468d5ac70f0Sopenharmony_ci\code
469d5ac70f0Sopenharmony_ciint change_tempo(snd_seq_t *handle, int q, unsigned int tempo)
470d5ac70f0Sopenharmony_ci{
471d5ac70f0Sopenharmony_ci	snd_seq_event_t ev;
472d5ac70f0Sopenharmony_ci	snd_seq_ev_clear(&ev);
473d5ac70f0Sopenharmony_ci	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
474d5ac70f0Sopenharmony_ci	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
475d5ac70f0Sopenharmony_ci	ev.source.client = my_client_id;
476d5ac70f0Sopenharmony_ci	ev.source.port = my_port_id;
477d5ac70f0Sopenharmony_ci	ev.queue = SND_SEQ_QUEUE_DIRECT; // no scheduling
478d5ac70f0Sopenharmony_ci	ev.data.queue.queue = q;	// affected queue id
479d5ac70f0Sopenharmony_ci	ev.data.queue.value = tempo;	// new tempo in microsec.
480d5ac70f0Sopenharmony_ci	return snd_seq_event_output(handle, &ev);
481d5ac70f0Sopenharmony_ci}
482d5ac70f0Sopenharmony_ci\endcode
483d5ac70f0Sopenharmony_ciThere is a helper function to do this easily,
484d5ac70f0Sopenharmony_ci#snd_seq_change_queue_tempo().
485d5ac70f0Sopenharmony_ciSet NULL to the last argument, if you don't need any
486d5ac70f0Sopenharmony_cispecial settings.
487d5ac70f0Sopenharmony_ci
488d5ac70f0Sopenharmony_ciIn the above example, the tempo is changed immediately after
489d5ac70f0Sopenharmony_cithe buffer is flushed by #snd_seq_drain_output() call.
490d5ac70f0Sopenharmony_ciYou can schedule the event in a certain queue so that the tempo
491d5ac70f0Sopenharmony_cichange happens at the scheduled time, too.
492d5ac70f0Sopenharmony_ci
493d5ac70f0Sopenharmony_ci\subsection seq_ev_start Starting and stopping a queue
494d5ac70f0Sopenharmony_ci
495d5ac70f0Sopenharmony_ciTo start, stop, or continue a queue, you need to send a queue-control
496d5ac70f0Sopenharmony_cievent to the system timer port as well.  There are helper functions,
497d5ac70f0Sopenharmony_ci#snd_seq_start_queue(), #snd_seq_stop_queue() and
498d5ac70f0Sopenharmony_ci#snd_seq_continue_queue().
499d5ac70f0Sopenharmony_ciNote that if the last argument of these functions is NULL, the
500d5ac70f0Sopenharmony_cievent is sent (i.e. operated) immediately after the buffer flush.
501d5ac70f0Sopenharmony_ciIf you want to schedule the event at the certain time, set up
502d5ac70f0Sopenharmony_cithe event record and provide the pointer of that event record as the
503d5ac70f0Sopenharmony_ciargument.
504d5ac70f0Sopenharmony_ci
505d5ac70f0Sopenharmony_ciOnly calling these functions doesn't deliver the event to the
506d5ac70f0Sopenharmony_cisequencer core but only put to the output buffer.  You'll need to
507d5ac70f0Sopenharmony_cicall #snd_seq_drain_output() eventually.
508d5ac70f0Sopenharmony_ci
509d5ac70f0Sopenharmony_ci
510d5ac70f0Sopenharmony_ci\section seq_subs_more More inside the subscription
511d5ac70f0Sopenharmony_ci
512d5ac70f0Sopenharmony_ci\subsection seq_subs_perm Permissions
513d5ac70f0Sopenharmony_ci
514d5ac70f0Sopenharmony_ciEach ALSA port can have capability flags.
515d5ac70f0Sopenharmony_ciThe most basic capability flags are
516d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE.
517d5ac70f0Sopenharmony_ciThe former means that the port allows to send events to other ports,
518d5ac70f0Sopenharmony_ciwhereas the latter capability means
519d5ac70f0Sopenharmony_cithat the port allows to receive events from other ports.
520d5ac70f0Sopenharmony_ciYou may have noticed that meanings of \c READ and \c WRITE
521d5ac70f0Sopenharmony_ciare permissions of the port from the viewpoint of other ports.
522d5ac70f0Sopenharmony_ci
523d5ac70f0Sopenharmony_ciFor allowing subscription from/to other clients, another capability
524d5ac70f0Sopenharmony_ciflags must be set together with read/write capabilities above.
525d5ac70f0Sopenharmony_ciFor allowing read and write subscriptions,
526d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_READ and
527d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_WRITE are used,
528d5ac70f0Sopenharmony_cirespectively.
529d5ac70f0Sopenharmony_ciFor example, the port with MIDI input device always has
530d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_READ capability,
531d5ac70f0Sopenharmony_ciand the port with MIDI output device always has
532d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_WRITE capability together with
533d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE capabilities,
534d5ac70f0Sopenharmony_cirespectively.
535d5ac70f0Sopenharmony_ciObviously, these flags have no influence
536d5ac70f0Sopenharmony_ciif \c READ or \c WRITE> capability is not set.
537d5ac70f0Sopenharmony_ci
538d5ac70f0Sopenharmony_ciNote that these flags are not necessary if the client subscribes itself
539d5ac70f0Sopenharmony_cito the specified port.
540d5ac70f0Sopenharmony_ciFor example, when a port makes READ subscription
541d5ac70f0Sopenharmony_cito MIDI input port, this port must have #SND_SEQ_PORT_CAP_WRITE capability,
542d5ac70f0Sopenharmony_cibut no #SND_SEQ_PORT_CAP_SUBS_WRITE capability is required.
543d5ac70f0Sopenharmony_ciOnly MIDI input port must have #SND_SEQ_PORT_CAP_SUBS_READ capability.
544d5ac70f0Sopenharmony_ci
545d5ac70f0Sopenharmony_ciAs default, the connection of ports via the third client is always allowed
546d5ac70f0Sopenharmony_ciif proper read and write (subscription) capabilities are set both to the
547d5ac70f0Sopenharmony_cisource and destination ports.
548d5ac70f0Sopenharmony_ciFor prohibiting this behavior, set a capability
549d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_NO_EXPORT to the port.
550d5ac70f0Sopenharmony_ciIf this flag is set, subscription must be done by sender or receiver
551d5ac70f0Sopenharmony_ciclient itself.
552d5ac70f0Sopenharmony_ciIt is useful to avoid unexpected disconnection.
553d5ac70f0Sopenharmony_ciThe ports which won't accept subscription should have this capability
554d5ac70f0Sopenharmony_cifor better security.
555d5ac70f0Sopenharmony_ci
556d5ac70f0Sopenharmony_ci\subsection seq_subs_handle Subscription handlers
557d5ac70f0Sopenharmony_ci
558d5ac70f0Sopenharmony_ciIn ALSA library, subscription is done via
559d5ac70f0Sopenharmony_ci#snd_seq_subscribe_port() function.
560d5ac70f0Sopenharmony_ciIt takes the argument of #snd_seq_port_subscribe_t record pointer.
561d5ac70f0Sopenharmony_ciSuppose that you have a client which will receive data from
562d5ac70f0Sopenharmony_cia MIDI input device.  The source and destination addresses
563d5ac70f0Sopenharmony_ciare like the below;
564d5ac70f0Sopenharmony_ci\code
565d5ac70f0Sopenharmony_cisnd_seq_addr_t sender, dest;
566d5ac70f0Sopenharmony_cisender.client = MIDI_input_client;
567d5ac70f0Sopenharmony_cisender.port = MIDI_input_port;
568d5ac70f0Sopenharmony_cidest.client = my_client;
569d5ac70f0Sopenharmony_cidest.port = my_port;
570d5ac70f0Sopenharmony_ci\endcode
571d5ac70f0Sopenharmony_ciTo set these values as the connection call like this.
572d5ac70f0Sopenharmony_ci\code
573d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_t *subs;
574d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_alloca(&subs);
575d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_sender(subs, &sender);
576d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_dest(subs, &dest);
577d5ac70f0Sopenharmony_cisnd_seq_subscribe_port(handle, subs);
578d5ac70f0Sopenharmony_ci\endcode
579d5ac70f0Sopenharmony_ci
580d5ac70f0Sopenharmony_ciWhen the connection should be exclusively done only between
581d5ac70f0Sopenharmony_cia certain pair, set <i>exclusive</i> attribute to the subscription
582d5ac70f0Sopenharmony_cirecord before calling #snd_seq_subscribe_port.
583d5ac70f0Sopenharmony_ci\code
584d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_exclusive(subs, 1);
585d5ac70f0Sopenharmony_ci\endcode
586d5ac70f0Sopenharmony_ciThe succeeding subscriptions will be refused.
587d5ac70f0Sopenharmony_ci
588d5ac70f0Sopenharmony_ciThe timestamp can be updated independently on each connection.
589d5ac70f0Sopenharmony_ciWhen set up, the timestamp of incoming queue to the destination port
590d5ac70f0Sopenharmony_ciis updated automatically to the time of the specified queue.
591d5ac70f0Sopenharmony_ci\code
592d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_time_update(subs, 1);
593d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_queue(subs, q);
594d5ac70f0Sopenharmony_ci\endcode
595d5ac70f0Sopenharmony_ciFor getting the wallclock time (sec/nsec pair), set <i>real</i> attribute:
596d5ac70f0Sopenharmony_ci\code
597d5ac70f0Sopenharmony_cisnd_seq_port_subscribe_set_time_real(subs, 1);
598d5ac70f0Sopenharmony_ci\endcode
599d5ac70f0Sopenharmony_ciOtherwise, the timestamp is stored in tick unit.
600d5ac70f0Sopenharmony_ciThis feature is useful when receiving events from MIDI input device.
601d5ac70f0Sopenharmony_ciThe event time is automatically set in the event record.
602d5ac70f0Sopenharmony_ci
603d5ac70f0Sopenharmony_ciNote that an outsider client may connect other ports.
604d5ac70f0Sopenharmony_ciIn this case, however, the subscription may be refused
605d5ac70f0Sopenharmony_ciif #SND_SEQ_PORT_CAP_NO_EXPORT capability is set in either sender or receiver port.
606d5ac70f0Sopenharmony_ci
607d5ac70f0Sopenharmony_ci\section seq_subs_ex Examples of subscription
608d5ac70f0Sopenharmony_ci
609d5ac70f0Sopenharmony_ci\subsection seq_subs_ex_capt Capture from keyboard
610d5ac70f0Sopenharmony_ci
611d5ac70f0Sopenharmony_ciAssume MIDI input port = 64:0, application port = 128:0, and
612d5ac70f0Sopenharmony_ciqueue for timestamp = 1 with real-time stamp.
613d5ac70f0Sopenharmony_ciThe application port must have capability #SND_SEQ_PORT_CAP_WRITE.
614d5ac70f0Sopenharmony_ci\code
615d5ac70f0Sopenharmony_civoid capture_keyboard(snd_seq_t *seq)
616d5ac70f0Sopenharmony_ci{
617d5ac70f0Sopenharmony_ci        snd_seq_addr_t sender, dest;
618d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_t *subs;
619d5ac70f0Sopenharmony_ci        sender.client = 64;
620d5ac70f0Sopenharmony_ci        sender.port = 0;
621d5ac70f0Sopenharmony_ci        dest.client = 128;
622d5ac70f0Sopenharmony_ci        dest.port = 0;
623d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_alloca(&subs);
624d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_sender(subs, &sender);
625d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_dest(subs, &dest);
626d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_queue(subs, 1);
627d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_time_update(subs, 1);
628d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_time_real(subs, 1);
629d5ac70f0Sopenharmony_ci        snd_seq_subscribe_port(seq, subs);
630d5ac70f0Sopenharmony_ci}
631d5ac70f0Sopenharmony_ci\endcode
632d5ac70f0Sopenharmony_ci
633d5ac70f0Sopenharmony_ci\subsection seq_subs_ex_out Output to MIDI device
634d5ac70f0Sopenharmony_ci
635d5ac70f0Sopenharmony_ciAssume MIDI output port = 65:1 and application port = 128:0.
636d5ac70f0Sopenharmony_ciThe application port must have capability #SND_SEQ_PORT_CAP_READ.
637d5ac70f0Sopenharmony_ci\code
638d5ac70f0Sopenharmony_civoid subscribe_output(snd_seq_t *seq)
639d5ac70f0Sopenharmony_ci{
640d5ac70f0Sopenharmony_ci        snd_seq_addr_t sender, dest;
641d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_t *subs;
642d5ac70f0Sopenharmony_ci        sender.client = 128;
643d5ac70f0Sopenharmony_ci        sender.port = 0;
644d5ac70f0Sopenharmony_ci        dest.client = 65;
645d5ac70f0Sopenharmony_ci        dest.port = 1;
646d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_alloca(&subs);
647d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_sender(subs, &sender);
648d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_dest(subs, &dest);
649d5ac70f0Sopenharmony_ci        snd_seq_subscribe_port(seq, subs);
650d5ac70f0Sopenharmony_ci}
651d5ac70f0Sopenharmony_ci\endcode
652d5ac70f0Sopenharmony_ciThis example can be simplified by using #snd_seq_connect_to() function.
653d5ac70f0Sopenharmony_ci\code
654d5ac70f0Sopenharmony_civoid subscribe_output(snd_seq_t *seq)
655d5ac70f0Sopenharmony_ci{
656d5ac70f0Sopenharmony_ci        snd_seq_connect_to(seq, 0, 65, 1);
657d5ac70f0Sopenharmony_ci}
658d5ac70f0Sopenharmony_ci\endcode
659d5ac70f0Sopenharmony_ci
660d5ac70f0Sopenharmony_ci\subsection seq_subs_ex_arbit Arbitrary connection
661d5ac70f0Sopenharmony_ci
662d5ac70f0Sopenharmony_ciAssume connection from application 128:0 to 129:0,
663d5ac70f0Sopenharmony_ciand that subscription is done by the third application (130:0).
664d5ac70f0Sopenharmony_ciThe sender must have capabilities both
665d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_READ and
666d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_READ,
667d5ac70f0Sopenharmony_ciand the receiver
668d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_WRITE and
669d5ac70f0Sopenharmony_ci#SND_SEQ_PORT_CAP_SUBS_WRITE, respectively.
670d5ac70f0Sopenharmony_ci\code
671d5ac70f0Sopenharmony_ci// ..in the third application (130:0) ..
672d5ac70f0Sopenharmony_civoid coupling(snd_seq_t *seq)
673d5ac70f0Sopenharmony_ci{
674d5ac70f0Sopenharmony_ci        snd_seq_addr_t sender, dest;
675d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_t *subs;
676d5ac70f0Sopenharmony_ci        sender.client = 128;
677d5ac70f0Sopenharmony_ci        sender.port = 0;
678d5ac70f0Sopenharmony_ci        dest.client = 129;
679d5ac70f0Sopenharmony_ci        dest.port = 0;
680d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_alloca(&subs);
681d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_sender(subs, &sender);
682d5ac70f0Sopenharmony_ci        snd_seq_port_subscribe_set_dest(subs, &dest);
683d5ac70f0Sopenharmony_ci        snd_seq_subscribe_port(seq, subs);
684d5ac70f0Sopenharmony_ci}
685d5ac70f0Sopenharmony_ci\endcode
686d5ac70f0Sopenharmony_ci
687d5ac70f0Sopenharmony_ci\section seq_ex_event Event Processing
688d5ac70f0Sopenharmony_ci
689d5ac70f0Sopenharmony_ci\subsection seq_ex_address Addressing
690d5ac70f0Sopenharmony_ci
691d5ac70f0Sopenharmony_ciNow, two ports are connected by subscription.  Then how to send events?
692d5ac70f0Sopenharmony_ci
693d5ac70f0Sopenharmony_ciThe subscribed port doesn't have to know the exact sender address.
694d5ac70f0Sopenharmony_ciInstead, there is a special address for subscribers,
695d5ac70f0Sopenharmony_ci#SND_SEQ_ADDRESS_SUBSCRIBERS.
696d5ac70f0Sopenharmony_ciThe sender must set this value as the destination client.
697d5ac70f0Sopenharmony_ciDestination port is ignored.
698d5ac70f0Sopenharmony_ci
699d5ac70f0Sopenharmony_ciThe other values in source and destination addresses are identical with
700d5ac70f0Sopenharmony_cithe normal event record.
701d5ac70f0Sopenharmony_ciIf the event is scheduled, proper queue and timestamp values must be set.
702d5ac70f0Sopenharmony_ci
703d5ac70f0Sopenharmony_ciThere is a convenient function to set the address in an event record.
704d5ac70f0Sopenharmony_ciIn order to set destination as subscribers, use
705d5ac70f0Sopenharmony_ci#snd_seq_ev_set_subs().
706d5ac70f0Sopenharmony_ci
707d5ac70f0Sopenharmony_ci\subsection Scheduled Delivery
708d5ac70f0Sopenharmony_ci
709d5ac70f0Sopenharmony_ciIf we send an event at the scheduled time <code>t</code> (tick)
710d5ac70f0Sopenharmony_cion the queue <code>Q</code>,
711d5ac70f0Sopenharmony_cithe sender must set both schedule queue and time in the
712d5ac70f0Sopenharmony_cievent record.
713d5ac70f0Sopenharmony_ciThe program appears like this:
714d5ac70f0Sopenharmony_ci\code
715d5ac70f0Sopenharmony_civoid schedule_event(snd_seq_t *seq)
716d5ac70f0Sopenharmony_ci{
717d5ac70f0Sopenharmony_ci        snd_seq_event_t ev;
718d5ac70f0Sopenharmony_ci
719d5ac70f0Sopenharmony_ci        snd_seq_ev_clear(&ev);
720d5ac70f0Sopenharmony_ci        snd_seq_ev_set_source(&ev, my_port);
721d5ac70f0Sopenharmony_ci        snd_seq_ev_set_subs(&ev);
722d5ac70f0Sopenharmony_ci        snd_seq_ev_schedule_tick(&ev, Q, 0, t);
723d5ac70f0Sopenharmony_ci        ... // set event type, data, so on..
724d5ac70f0Sopenharmony_ci
725d5ac70f0Sopenharmony_ci        snd_seq_event_output(seq, &ev);
726d5ac70f0Sopenharmony_ci        ...
727d5ac70f0Sopenharmony_ci        snd_seq_drain_output(seq);  // if necessary
728d5ac70f0Sopenharmony_ci}
729d5ac70f0Sopenharmony_ci\endcode
730d5ac70f0Sopenharmony_ciOf course, you can use realtime stamp, too.
731d5ac70f0Sopenharmony_ci
732d5ac70f0Sopenharmony_ci\subsection seq_ex_direct Direct Delivery
733d5ac70f0Sopenharmony_ci
734d5ac70f0Sopenharmony_ciIf the event is sent immediately without enqueued, the sender doesn't take
735d5ac70f0Sopenharmony_cicare of queue and timestamp.
736d5ac70f0Sopenharmony_ciAs well as the case above, there is a function to set the direct delivery,
737d5ac70f0Sopenharmony_ci#snd_seq_ev_set_direct().
738d5ac70f0Sopenharmony_ciThe program can be more simplified as follows:
739d5ac70f0Sopenharmony_ci\code
740d5ac70f0Sopenharmony_civoid direct_delivery(snd_seq_t *seq)
741d5ac70f0Sopenharmony_ci{
742d5ac70f0Sopenharmony_ci        snd_seq_event_t ev;
743d5ac70f0Sopenharmony_ci
744d5ac70f0Sopenharmony_ci        snd_seq_ev_clear(&ev);
745d5ac70f0Sopenharmony_ci        snd_seq_ev_set_source(&ev, port);
746d5ac70f0Sopenharmony_ci        snd_seq_ev_set_subs(&ev);
747d5ac70f0Sopenharmony_ci        snd_seq_ev_set_direct(&ev);
748d5ac70f0Sopenharmony_ci        ... // set event type, data, so on..
749d5ac70f0Sopenharmony_ci
750d5ac70f0Sopenharmony_ci        snd_seq_event_output(seq, &ev);
751d5ac70f0Sopenharmony_ci        snd_seq_drain_output(seq);
752d5ac70f0Sopenharmony_ci}
753d5ac70f0Sopenharmony_ci\endcode
754d5ac70f0Sopenharmony_ciYou should flush event soon after output event.
755d5ac70f0Sopenharmony_ciOtherwise, the event is enqueued on output queue of ALSA library
756d5ac70f0Sopenharmony_ci(not in the kernel!), and will be never processed until
757d5ac70f0Sopenharmony_cithis queue becomes full.
758d5ac70f0Sopenharmony_ci
759d5ac70f0Sopenharmony_ci\subsection seq_ex_filter Filter Application
760d5ac70f0Sopenharmony_ci
761d5ac70f0Sopenharmony_ciA typical filter program, which receives an event and sends it immediately
762d5ac70f0Sopenharmony_ciafter some modification, will appear as following:
763d5ac70f0Sopenharmony_ci\code
764d5ac70f0Sopenharmony_civoid event_filter(snd_seq_t *seq, snd_seq_event_t *ev)
765d5ac70f0Sopenharmony_ci{
766d5ac70f0Sopenharmony_ci        while (snd_seq_event_input(seq, &ev) >= 0) {
767d5ac70f0Sopenharmony_ci                //.. modify input event ..
768d5ac70f0Sopenharmony_ci
769d5ac70f0Sopenharmony_ci                snd_seq_ev_set_source(ev, my_port);
770d5ac70f0Sopenharmony_ci                snd_seq_ev_set_subs(ev);
771d5ac70f0Sopenharmony_ci                snd_seq_ev_set_direct(ev);
772d5ac70f0Sopenharmony_ci                snd_seq_event_output(seq, ev);
773d5ac70f0Sopenharmony_ci                snd_seq_drain_output(seq);
774d5ac70f0Sopenharmony_ci        }
775d5ac70f0Sopenharmony_ci}
776d5ac70f0Sopenharmony_ci\endcode
777d5ac70f0Sopenharmony_ci
778d5ac70f0Sopenharmony_ci*/
779d5ac70f0Sopenharmony_ci
780d5ac70f0Sopenharmony_ci#include "seq_local.h"
781d5ac70f0Sopenharmony_ci#include <poll.h>
782d5ac70f0Sopenharmony_ci
783d5ac70f0Sopenharmony_ci/****************************************************************************
784d5ac70f0Sopenharmony_ci *                                                                          *
785d5ac70f0Sopenharmony_ci *                                seq.h                                     *
786d5ac70f0Sopenharmony_ci *                              Sequencer                                   *
787d5ac70f0Sopenharmony_ci *                                                                          *
788d5ac70f0Sopenharmony_ci ****************************************************************************/
789d5ac70f0Sopenharmony_ci
790d5ac70f0Sopenharmony_ci/**
791d5ac70f0Sopenharmony_ci * \brief get identifier of sequencer handle
792d5ac70f0Sopenharmony_ci * \param seq sequencer handle
793d5ac70f0Sopenharmony_ci * \return ASCII identifier of sequencer handle
794d5ac70f0Sopenharmony_ci *
795d5ac70f0Sopenharmony_ci * Returns the ASCII identifier of the given sequencer handle. It's the same
796d5ac70f0Sopenharmony_ci * identifier specified in snd_seq_open().
797d5ac70f0Sopenharmony_ci *
798d5ac70f0Sopenharmony_ci * \sa snd_seq_open()
799d5ac70f0Sopenharmony_ci */
800d5ac70f0Sopenharmony_ciconst char *snd_seq_name(snd_seq_t *seq)
801d5ac70f0Sopenharmony_ci{
802d5ac70f0Sopenharmony_ci	assert(seq);
803d5ac70f0Sopenharmony_ci	return seq->name;
804d5ac70f0Sopenharmony_ci}
805d5ac70f0Sopenharmony_ci
806d5ac70f0Sopenharmony_ci/**
807d5ac70f0Sopenharmony_ci * \brief get type of sequencer handle
808d5ac70f0Sopenharmony_ci * \param seq sequencer handle
809d5ac70f0Sopenharmony_ci * \return type of sequencer handle
810d5ac70f0Sopenharmony_ci *
811d5ac70f0Sopenharmony_ci * Returns the type #snd_seq_type_t of the given sequencer handle.
812d5ac70f0Sopenharmony_ci *
813d5ac70f0Sopenharmony_ci * \sa snd_seq_open()
814d5ac70f0Sopenharmony_ci */
815d5ac70f0Sopenharmony_cisnd_seq_type_t snd_seq_type(snd_seq_t *seq)
816d5ac70f0Sopenharmony_ci{
817d5ac70f0Sopenharmony_ci	assert(seq);
818d5ac70f0Sopenharmony_ci	return seq->type;
819d5ac70f0Sopenharmony_ci}
820d5ac70f0Sopenharmony_ci
821d5ac70f0Sopenharmony_cistatic int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
822d5ac70f0Sopenharmony_ci			     snd_config_t *seq_root, snd_config_t *seq_conf,
823d5ac70f0Sopenharmony_ci			     int streams, int mode)
824d5ac70f0Sopenharmony_ci{
825d5ac70f0Sopenharmony_ci	const char *str;
826d5ac70f0Sopenharmony_ci	char buf[256], errbuf[256];
827d5ac70f0Sopenharmony_ci	int err;
828d5ac70f0Sopenharmony_ci	snd_config_t *conf, *type_conf = NULL;
829d5ac70f0Sopenharmony_ci	snd_config_iterator_t i, next;
830d5ac70f0Sopenharmony_ci	const char *id;
831d5ac70f0Sopenharmony_ci	const char *lib = NULL, *open_name = NULL;
832d5ac70f0Sopenharmony_ci	int (*open_func)(snd_seq_t **, const char *,
833d5ac70f0Sopenharmony_ci			 snd_config_t *, snd_config_t *,
834d5ac70f0Sopenharmony_ci			 int, int) = NULL;
835d5ac70f0Sopenharmony_ci#ifndef PIC
836d5ac70f0Sopenharmony_ci	extern void *snd_seq_open_symbols(void);
837d5ac70f0Sopenharmony_ci#endif
838d5ac70f0Sopenharmony_ci	void *h = NULL;
839d5ac70f0Sopenharmony_ci	if (snd_config_get_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
840d5ac70f0Sopenharmony_ci		if (name)
841d5ac70f0Sopenharmony_ci			SNDERR("Invalid type for SEQ %s definition", name);
842d5ac70f0Sopenharmony_ci		else
843d5ac70f0Sopenharmony_ci			SNDERR("Invalid type for SEQ definition");
844d5ac70f0Sopenharmony_ci		return -EINVAL;
845d5ac70f0Sopenharmony_ci	}
846d5ac70f0Sopenharmony_ci	err = snd_config_search(seq_conf, "type", &conf);
847d5ac70f0Sopenharmony_ci	if (err < 0) {
848d5ac70f0Sopenharmony_ci		SNDERR("type is not defined");
849d5ac70f0Sopenharmony_ci		return err;
850d5ac70f0Sopenharmony_ci	}
851d5ac70f0Sopenharmony_ci	err = snd_config_get_id(conf, &id);
852d5ac70f0Sopenharmony_ci	if (err < 0) {
853d5ac70f0Sopenharmony_ci		SNDERR("unable to get id");
854d5ac70f0Sopenharmony_ci		return err;
855d5ac70f0Sopenharmony_ci	}
856d5ac70f0Sopenharmony_ci	err = snd_config_get_string(conf, &str);
857d5ac70f0Sopenharmony_ci	if (err < 0) {
858d5ac70f0Sopenharmony_ci		SNDERR("Invalid type for %s", id);
859d5ac70f0Sopenharmony_ci		return err;
860d5ac70f0Sopenharmony_ci	}
861d5ac70f0Sopenharmony_ci	err = snd_config_search_definition(seq_root, "seq_type", str, &type_conf);
862d5ac70f0Sopenharmony_ci	if (err >= 0) {
863d5ac70f0Sopenharmony_ci		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
864d5ac70f0Sopenharmony_ci			SNDERR("Invalid type for SEQ type %s definition", str);
865d5ac70f0Sopenharmony_ci			goto _err;
866d5ac70f0Sopenharmony_ci		}
867d5ac70f0Sopenharmony_ci		snd_config_for_each(i, next, type_conf) {
868d5ac70f0Sopenharmony_ci			snd_config_t *n = snd_config_iterator_entry(i);
869d5ac70f0Sopenharmony_ci			const char *id;
870d5ac70f0Sopenharmony_ci			if (snd_config_get_id(n, &id) < 0)
871d5ac70f0Sopenharmony_ci				continue;
872d5ac70f0Sopenharmony_ci			if (strcmp(id, "comment") == 0)
873d5ac70f0Sopenharmony_ci				continue;
874d5ac70f0Sopenharmony_ci			if (strcmp(id, "lib") == 0) {
875d5ac70f0Sopenharmony_ci				err = snd_config_get_string(n, &lib);
876d5ac70f0Sopenharmony_ci				if (err < 0) {
877d5ac70f0Sopenharmony_ci					SNDERR("Invalid type for %s", id);
878d5ac70f0Sopenharmony_ci					goto _err;
879d5ac70f0Sopenharmony_ci				}
880d5ac70f0Sopenharmony_ci				continue;
881d5ac70f0Sopenharmony_ci			}
882d5ac70f0Sopenharmony_ci			if (strcmp(id, "open") == 0) {
883d5ac70f0Sopenharmony_ci				err = snd_config_get_string(n, &open_name);
884d5ac70f0Sopenharmony_ci				if (err < 0) {
885d5ac70f0Sopenharmony_ci					SNDERR("Invalid type for %s", id);
886d5ac70f0Sopenharmony_ci					goto _err;
887d5ac70f0Sopenharmony_ci				}
888d5ac70f0Sopenharmony_ci				continue;
889d5ac70f0Sopenharmony_ci			}
890d5ac70f0Sopenharmony_ci			SNDERR("Unknown field %s", id);
891d5ac70f0Sopenharmony_ci			err = -EINVAL;
892d5ac70f0Sopenharmony_ci			goto _err;
893d5ac70f0Sopenharmony_ci		}
894d5ac70f0Sopenharmony_ci	}
895d5ac70f0Sopenharmony_ci	if (!open_name) {
896d5ac70f0Sopenharmony_ci		open_name = buf;
897d5ac70f0Sopenharmony_ci		snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
898d5ac70f0Sopenharmony_ci	}
899d5ac70f0Sopenharmony_ci#ifndef PIC
900d5ac70f0Sopenharmony_ci	snd_seq_open_symbols();
901d5ac70f0Sopenharmony_ci#endif
902d5ac70f0Sopenharmony_ci	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
903d5ac70f0Sopenharmony_ci	if (h)
904d5ac70f0Sopenharmony_ci		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_SEQ_DLSYM_VERSION));
905d5ac70f0Sopenharmony_ci	err = 0;
906d5ac70f0Sopenharmony_ci	if (!h) {
907d5ac70f0Sopenharmony_ci		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
908d5ac70f0Sopenharmony_ci		err = -ENOENT;
909d5ac70f0Sopenharmony_ci	} else if (!open_func) {
910d5ac70f0Sopenharmony_ci		SNDERR("symbol %s is not defined inside %s", open_name, lib);
911d5ac70f0Sopenharmony_ci		snd_dlclose(h);
912d5ac70f0Sopenharmony_ci		err = -ENXIO;
913d5ac70f0Sopenharmony_ci	}
914d5ac70f0Sopenharmony_ci       _err:
915d5ac70f0Sopenharmony_ci	if (type_conf)
916d5ac70f0Sopenharmony_ci		snd_config_delete(type_conf);
917d5ac70f0Sopenharmony_ci	if (! err) {
918d5ac70f0Sopenharmony_ci		err = open_func(seqp, name, seq_root, seq_conf, streams, mode);
919d5ac70f0Sopenharmony_ci		if (err < 0)
920d5ac70f0Sopenharmony_ci			snd_dlclose(h);
921d5ac70f0Sopenharmony_ci		else
922d5ac70f0Sopenharmony_ci			(*seqp)->dl_handle = h;
923d5ac70f0Sopenharmony_ci	}
924d5ac70f0Sopenharmony_ci	return err;
925d5ac70f0Sopenharmony_ci}
926d5ac70f0Sopenharmony_ci
927d5ac70f0Sopenharmony_cistatic int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
928d5ac70f0Sopenharmony_ci				 const char *name, int streams, int mode,
929d5ac70f0Sopenharmony_ci				 int hop)
930d5ac70f0Sopenharmony_ci{
931d5ac70f0Sopenharmony_ci	int err;
932d5ac70f0Sopenharmony_ci	snd_config_t *seq_conf;
933d5ac70f0Sopenharmony_ci	err = snd_config_search_definition(root, "seq", name, &seq_conf);
934d5ac70f0Sopenharmony_ci	if (err < 0) {
935d5ac70f0Sopenharmony_ci		SNDERR("Unknown SEQ %s", name);
936d5ac70f0Sopenharmony_ci		return err;
937d5ac70f0Sopenharmony_ci	}
938d5ac70f0Sopenharmony_ci	snd_config_set_hop(seq_conf, hop);
939d5ac70f0Sopenharmony_ci	err = snd_seq_open_conf(seqp, name, root, seq_conf, streams, mode);
940d5ac70f0Sopenharmony_ci	snd_config_delete(seq_conf);
941d5ac70f0Sopenharmony_ci	return err;
942d5ac70f0Sopenharmony_ci}
943d5ac70f0Sopenharmony_ci
944d5ac70f0Sopenharmony_ci
945d5ac70f0Sopenharmony_ci/**
946d5ac70f0Sopenharmony_ci * \brief Open the ALSA sequencer
947d5ac70f0Sopenharmony_ci *
948d5ac70f0Sopenharmony_ci * \param seqp Pointer to a snd_seq_t pointer.  This pointer must be
949d5ac70f0Sopenharmony_ci * kept and passed to most of the other sequencer functions.
950d5ac70f0Sopenharmony_ci * \param name The sequencer's "name".  This is \em not a name you make
951d5ac70f0Sopenharmony_ci * up for your own purposes; it has special significance to the ALSA
952d5ac70f0Sopenharmony_ci * library.  Usually you need to pass \c "default" here.
953d5ac70f0Sopenharmony_ci * \param streams The read/write mode of the sequencer.  Can be one of
954d5ac70f0Sopenharmony_ci * three values:
955d5ac70f0Sopenharmony_ci * - #SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
956d5ac70f0Sopenharmony_ci * - #SND_SEQ_OPEN_INPUT - open the sequencer for input only
957d5ac70f0Sopenharmony_ci * - #SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
958d5ac70f0Sopenharmony_ci * \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
959d5ac70f0Sopenharmony_ci * \c O_RDWR respectively and used as the second argument to the C library
960d5ac70f0Sopenharmony_ci * open() call.
961d5ac70f0Sopenharmony_ci * \param mode Optional modifier.  Can be either 0, or
962d5ac70f0Sopenharmony_ci * #SND_SEQ_NONBLOCK, which will make read/write operations
963d5ac70f0Sopenharmony_ci * non-blocking.  This can also be set later using #snd_seq_nonblock().
964d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
965d5ac70f0Sopenharmony_ci *
966d5ac70f0Sopenharmony_ci * Creates a new handle and opens a connection to the kernel
967d5ac70f0Sopenharmony_ci * sequencer interface.
968d5ac70f0Sopenharmony_ci * After a client is created successfully, an event
969d5ac70f0Sopenharmony_ci * with #SND_SEQ_EVENT_CLIENT_START is broadcast to announce port.
970d5ac70f0Sopenharmony_ci *
971d5ac70f0Sopenharmony_ci * \sa snd_seq_open_lconf(), snd_seq_close(), snd_seq_type(), snd_seq_name(),
972d5ac70f0Sopenharmony_ci *     snd_seq_nonblock(), snd_seq_client_id()
973d5ac70f0Sopenharmony_ci */
974d5ac70f0Sopenharmony_ciint snd_seq_open(snd_seq_t **seqp, const char *name,
975d5ac70f0Sopenharmony_ci		 int streams, int mode)
976d5ac70f0Sopenharmony_ci{
977d5ac70f0Sopenharmony_ci	snd_config_t *top;
978d5ac70f0Sopenharmony_ci	int err;
979d5ac70f0Sopenharmony_ci
980d5ac70f0Sopenharmony_ci	assert(seqp && name);
981d5ac70f0Sopenharmony_ci	if (_snd_is_ucm_device(name)) {
982d5ac70f0Sopenharmony_ci		name = uc_mgr_alibcfg_by_device(&top, name);
983d5ac70f0Sopenharmony_ci		if (name == NULL)
984d5ac70f0Sopenharmony_ci			return -ENODEV;
985d5ac70f0Sopenharmony_ci	} else {
986d5ac70f0Sopenharmony_ci		err = snd_config_update_ref(&top);
987d5ac70f0Sopenharmony_ci		if (err < 0)
988d5ac70f0Sopenharmony_ci			return err;
989d5ac70f0Sopenharmony_ci	}
990d5ac70f0Sopenharmony_ci	err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
991d5ac70f0Sopenharmony_ci	snd_config_unref(top);
992d5ac70f0Sopenharmony_ci	return err;
993d5ac70f0Sopenharmony_ci}
994d5ac70f0Sopenharmony_ci
995d5ac70f0Sopenharmony_ci/**
996d5ac70f0Sopenharmony_ci * \brief Open the ALSA sequencer using local configuration
997d5ac70f0Sopenharmony_ci *
998d5ac70f0Sopenharmony_ci * \param seqp Pointer to a snd_seq_t pointer.
999d5ac70f0Sopenharmony_ci * \param name The name to open
1000d5ac70f0Sopenharmony_ci * \param streams The read/write mode of the sequencer.
1001d5ac70f0Sopenharmony_ci * \param mode Optional modifier
1002d5ac70f0Sopenharmony_ci * \param lconf Local configuration
1003d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1004d5ac70f0Sopenharmony_ci *
1005d5ac70f0Sopenharmony_ci * See the snd_seq_open() function for further details. The extension
1006d5ac70f0Sopenharmony_ci * is that the given configuration is used to resolve abstract name.
1007d5ac70f0Sopenharmony_ci *
1008d5ac70f0Sopenharmony_ci * \sa snd_seq_open()
1009d5ac70f0Sopenharmony_ci */
1010d5ac70f0Sopenharmony_ciint snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1011d5ac70f0Sopenharmony_ci		       int streams, int mode, snd_config_t *lconf)
1012d5ac70f0Sopenharmony_ci{
1013d5ac70f0Sopenharmony_ci	assert(seqp && name && lconf);
1014d5ac70f0Sopenharmony_ci	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
1015d5ac70f0Sopenharmony_ci}
1016d5ac70f0Sopenharmony_ci
1017d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN
1018d5ac70f0Sopenharmony_ciint _snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1019d5ac70f0Sopenharmony_ci			int streams, int mode, snd_config_t *lconf,
1020d5ac70f0Sopenharmony_ci			snd_config_t *parent_conf)
1021d5ac70f0Sopenharmony_ci{
1022d5ac70f0Sopenharmony_ci	int hop;
1023d5ac70f0Sopenharmony_ci	assert(seqp && name && lconf);
1024d5ac70f0Sopenharmony_ci	if ((hop = snd_config_check_hop(parent_conf)) < 0)
1025d5ac70f0Sopenharmony_ci		return hop;
1026d5ac70f0Sopenharmony_ci	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
1027d5ac70f0Sopenharmony_ci}
1028d5ac70f0Sopenharmony_ci#endif
1029d5ac70f0Sopenharmony_ci
1030d5ac70f0Sopenharmony_ci/**
1031d5ac70f0Sopenharmony_ci * \brief Close the sequencer
1032d5ac70f0Sopenharmony_ci * \param seq Handle returned from #snd_seq_open()
1033d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1034d5ac70f0Sopenharmony_ci *
1035d5ac70f0Sopenharmony_ci * Closes the sequencer client and releases its resources.
1036d5ac70f0Sopenharmony_ci * After a client is closed, an event with
1037d5ac70f0Sopenharmony_ci * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
1038d5ac70f0Sopenharmony_ci * The connection between other clients are disconnected.
1039d5ac70f0Sopenharmony_ci * Call this just before exiting your program.
1040d5ac70f0Sopenharmony_ci *
1041d5ac70f0Sopenharmony_ci * \sa snd_seq_close()
1042d5ac70f0Sopenharmony_ci */
1043d5ac70f0Sopenharmony_ciint snd_seq_close(snd_seq_t *seq)
1044d5ac70f0Sopenharmony_ci{
1045d5ac70f0Sopenharmony_ci	int err;
1046d5ac70f0Sopenharmony_ci	assert(seq);
1047d5ac70f0Sopenharmony_ci	err = seq->ops->close(seq);
1048d5ac70f0Sopenharmony_ci	if (seq->dl_handle)
1049d5ac70f0Sopenharmony_ci		snd_dlclose(seq->dl_handle);
1050d5ac70f0Sopenharmony_ci	free(seq->obuf);
1051d5ac70f0Sopenharmony_ci	free(seq->ibuf);
1052d5ac70f0Sopenharmony_ci	free(seq->tmpbuf);
1053d5ac70f0Sopenharmony_ci	free(seq->name);
1054d5ac70f0Sopenharmony_ci	free(seq);
1055d5ac70f0Sopenharmony_ci	return err;
1056d5ac70f0Sopenharmony_ci}
1057d5ac70f0Sopenharmony_ci
1058d5ac70f0Sopenharmony_ci/**
1059d5ac70f0Sopenharmony_ci * \brief Returns the number of poll descriptors
1060d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1061d5ac70f0Sopenharmony_ci * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
1062d5ac70f0Sopenharmony_ci * \return the number of poll descriptors.
1063d5ac70f0Sopenharmony_ci *
1064d5ac70f0Sopenharmony_ci * Get the number of poll descriptors.  The polling events to be checked
1065d5ac70f0Sopenharmony_ci * can be specified by the second argument.  When both input and output
1066d5ac70f0Sopenharmony_ci * are checked, pass \c POLLIN|POLLOUT
1067d5ac70f0Sopenharmony_ci *
1068d5ac70f0Sopenharmony_ci * \sa snd_seq_poll_descriptors()
1069d5ac70f0Sopenharmony_ci */
1070d5ac70f0Sopenharmony_ciint snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
1071d5ac70f0Sopenharmony_ci{
1072d5ac70f0Sopenharmony_ci	int result = 0;
1073d5ac70f0Sopenharmony_ci	assert(seq);
1074d5ac70f0Sopenharmony_ci	if (events & POLLIN) {
1075d5ac70f0Sopenharmony_ci		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1076d5ac70f0Sopenharmony_ci		result++;
1077d5ac70f0Sopenharmony_ci	}
1078d5ac70f0Sopenharmony_ci	if (events & POLLOUT) {
1079d5ac70f0Sopenharmony_ci		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1080d5ac70f0Sopenharmony_ci		result++;
1081d5ac70f0Sopenharmony_ci	}
1082d5ac70f0Sopenharmony_ci	return result ? 1 : 0;
1083d5ac70f0Sopenharmony_ci}
1084d5ac70f0Sopenharmony_ci
1085d5ac70f0Sopenharmony_ci/**
1086d5ac70f0Sopenharmony_ci * \brief Get poll descriptors
1087d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1088d5ac70f0Sopenharmony_ci * \param pfds array of poll descriptors
1089d5ac70f0Sopenharmony_ci * \param space space in the poll descriptor array
1090d5ac70f0Sopenharmony_ci * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
1091d5ac70f0Sopenharmony_ci * \return count of filled descriptors
1092d5ac70f0Sopenharmony_ci *
1093d5ac70f0Sopenharmony_ci * Get poll descriptors assigned to the sequencer handle.
1094d5ac70f0Sopenharmony_ci * Since a sequencer handle can duplex streams, you need to set which direction(s)
1095d5ac70f0Sopenharmony_ci * is/are polled in \a events argument.  When \c POLLIN bit is specified,
1096d5ac70f0Sopenharmony_ci * the incoming events to the ports are checked.
1097d5ac70f0Sopenharmony_ci *
1098d5ac70f0Sopenharmony_ci * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
1099d5ac70f0Sopenharmony_ci * instead of reading the pollfd structs directly.
1100d5ac70f0Sopenharmony_ci *
1101d5ac70f0Sopenharmony_ci * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
1102d5ac70f0Sopenharmony_ci */
1103d5ac70f0Sopenharmony_ciint snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
1104d5ac70f0Sopenharmony_ci{
1105d5ac70f0Sopenharmony_ci	short revents = 0;
1106d5ac70f0Sopenharmony_ci
1107d5ac70f0Sopenharmony_ci	assert(seq);
1108d5ac70f0Sopenharmony_ci	if ((events & POLLIN) && space >= 1) {
1109d5ac70f0Sopenharmony_ci		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1110d5ac70f0Sopenharmony_ci		revents |= POLLIN|POLLERR|POLLNVAL;
1111d5ac70f0Sopenharmony_ci	}
1112d5ac70f0Sopenharmony_ci	if ((events & POLLOUT) && space >= 1) {
1113d5ac70f0Sopenharmony_ci		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1114d5ac70f0Sopenharmony_ci		revents |= POLLOUT|POLLERR|POLLNVAL;
1115d5ac70f0Sopenharmony_ci	}
1116d5ac70f0Sopenharmony_ci	if (!revents)
1117d5ac70f0Sopenharmony_ci		return 0;
1118d5ac70f0Sopenharmony_ci	pfds->fd = seq->poll_fd;
1119d5ac70f0Sopenharmony_ci	pfds->events = revents;
1120d5ac70f0Sopenharmony_ci	return 1;
1121d5ac70f0Sopenharmony_ci}
1122d5ac70f0Sopenharmony_ci
1123d5ac70f0Sopenharmony_ci/**
1124d5ac70f0Sopenharmony_ci * \brief get returned events from poll descriptors
1125d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1126d5ac70f0Sopenharmony_ci * \param pfds array of poll descriptors
1127d5ac70f0Sopenharmony_ci * \param nfds count of poll descriptors
1128d5ac70f0Sopenharmony_ci * \param revents returned events
1129d5ac70f0Sopenharmony_ci * \return zero if success, otherwise a negative error code
1130d5ac70f0Sopenharmony_ci *
1131d5ac70f0Sopenharmony_ci * \sa snd_seq_poll_descriptors()
1132d5ac70f0Sopenharmony_ci */
1133d5ac70f0Sopenharmony_ciint snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1134d5ac70f0Sopenharmony_ci{
1135d5ac70f0Sopenharmony_ci        assert(seq && pfds && revents);
1136d5ac70f0Sopenharmony_ci        if (nfds == 1) {
1137d5ac70f0Sopenharmony_ci                *revents = pfds->revents;
1138d5ac70f0Sopenharmony_ci                return 0;
1139d5ac70f0Sopenharmony_ci        }
1140d5ac70f0Sopenharmony_ci        return -EINVAL;
1141d5ac70f0Sopenharmony_ci}
1142d5ac70f0Sopenharmony_ci
1143d5ac70f0Sopenharmony_ci/**
1144d5ac70f0Sopenharmony_ci * \brief Set nonblock mode
1145d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1146d5ac70f0Sopenharmony_ci * \param nonblock 0 = block, 1 = nonblock mode
1147d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1148d5ac70f0Sopenharmony_ci *
1149d5ac70f0Sopenharmony_ci * Change the blocking mode of the given client.
1150d5ac70f0Sopenharmony_ci * In block mode, the client falls into sleep when it fills the
1151d5ac70f0Sopenharmony_ci * output memory pool with full events.  The client will be woken up
1152d5ac70f0Sopenharmony_ci * after a certain amount of free space becomes available.
1153d5ac70f0Sopenharmony_ci *
1154d5ac70f0Sopenharmony_ci * \sa snd_seq_open()
1155d5ac70f0Sopenharmony_ci */
1156d5ac70f0Sopenharmony_ciint snd_seq_nonblock(snd_seq_t *seq, int nonblock)
1157d5ac70f0Sopenharmony_ci{
1158d5ac70f0Sopenharmony_ci	int err;
1159d5ac70f0Sopenharmony_ci	assert(seq);
1160d5ac70f0Sopenharmony_ci	err = seq->ops->nonblock(seq, nonblock);
1161d5ac70f0Sopenharmony_ci	if (err < 0)
1162d5ac70f0Sopenharmony_ci		return err;
1163d5ac70f0Sopenharmony_ci	if (nonblock)
1164d5ac70f0Sopenharmony_ci		seq->mode |= SND_SEQ_NONBLOCK;
1165d5ac70f0Sopenharmony_ci	else
1166d5ac70f0Sopenharmony_ci		seq->mode &= ~SND_SEQ_NONBLOCK;
1167d5ac70f0Sopenharmony_ci	return 0;
1168d5ac70f0Sopenharmony_ci}
1169d5ac70f0Sopenharmony_ci
1170d5ac70f0Sopenharmony_ci/**
1171d5ac70f0Sopenharmony_ci * \brief Get the client id
1172d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1173d5ac70f0Sopenharmony_ci * \return the client id
1174d5ac70f0Sopenharmony_ci *
1175d5ac70f0Sopenharmony_ci * Returns the id of the specified client.
1176d5ac70f0Sopenharmony_ci * If an error occurs, function returns the negative error code.
1177d5ac70f0Sopenharmony_ci * A client id is necessary to inquiry or to set the client information.
1178d5ac70f0Sopenharmony_ci * A user client is assigned from 128 to 191.
1179d5ac70f0Sopenharmony_ci *
1180d5ac70f0Sopenharmony_ci * \sa snd_seq_open()
1181d5ac70f0Sopenharmony_ci */
1182d5ac70f0Sopenharmony_ciint snd_seq_client_id(snd_seq_t *seq)
1183d5ac70f0Sopenharmony_ci{
1184d5ac70f0Sopenharmony_ci	assert(seq);
1185d5ac70f0Sopenharmony_ci	return seq->client;
1186d5ac70f0Sopenharmony_ci}
1187d5ac70f0Sopenharmony_ci
1188d5ac70f0Sopenharmony_ci/**
1189d5ac70f0Sopenharmony_ci * \brief Return the size of output buffer
1190d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1191d5ac70f0Sopenharmony_ci * \return the size of output buffer in bytes
1192d5ac70f0Sopenharmony_ci *
1193d5ac70f0Sopenharmony_ci * Obtains the size of output buffer.
1194d5ac70f0Sopenharmony_ci * This buffer is used to store decoded byte-stream of output events
1195d5ac70f0Sopenharmony_ci * before transferring to sequencer.
1196d5ac70f0Sopenharmony_ci *
1197d5ac70f0Sopenharmony_ci * \sa snd_seq_set_output_buffer_size()
1198d5ac70f0Sopenharmony_ci */
1199d5ac70f0Sopenharmony_cisize_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
1200d5ac70f0Sopenharmony_ci{
1201d5ac70f0Sopenharmony_ci	assert(seq);
1202d5ac70f0Sopenharmony_ci	if (!seq->obuf)
1203d5ac70f0Sopenharmony_ci		return 0;
1204d5ac70f0Sopenharmony_ci	return seq->obufsize;
1205d5ac70f0Sopenharmony_ci}
1206d5ac70f0Sopenharmony_ci
1207d5ac70f0Sopenharmony_cistatic inline size_t get_packet_size(snd_seq_t *seq)
1208d5ac70f0Sopenharmony_ci{
1209d5ac70f0Sopenharmony_ci	return seq->packet_size ? seq->packet_size : sizeof(snd_seq_event_t);
1210d5ac70f0Sopenharmony_ci}
1211d5ac70f0Sopenharmony_ci
1212d5ac70f0Sopenharmony_ci/**
1213d5ac70f0Sopenharmony_ci * \brief Return the size of input buffer
1214d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1215d5ac70f0Sopenharmony_ci * \return the size of input buffer in bytes
1216d5ac70f0Sopenharmony_ci *
1217d5ac70f0Sopenharmony_ci * Obtains the size of input buffer.
1218d5ac70f0Sopenharmony_ci * This buffer is used to read byte-stream of input events from sequencer.
1219d5ac70f0Sopenharmony_ci *
1220d5ac70f0Sopenharmony_ci * \sa snd_seq_set_input_buffer_size()
1221d5ac70f0Sopenharmony_ci */
1222d5ac70f0Sopenharmony_cisize_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
1223d5ac70f0Sopenharmony_ci{
1224d5ac70f0Sopenharmony_ci	assert(seq);
1225d5ac70f0Sopenharmony_ci	if (!seq->ibuf)
1226d5ac70f0Sopenharmony_ci		return 0;
1227d5ac70f0Sopenharmony_ci	return seq->ibufsize * get_packet_size(seq);
1228d5ac70f0Sopenharmony_ci}
1229d5ac70f0Sopenharmony_ci
1230d5ac70f0Sopenharmony_ci/**
1231d5ac70f0Sopenharmony_ci * \brief Change the size of output buffer
1232d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1233d5ac70f0Sopenharmony_ci * \param size the size of output buffer to be changed in bytes
1234d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1235d5ac70f0Sopenharmony_ci *
1236d5ac70f0Sopenharmony_ci * Changes the size of output buffer.
1237d5ac70f0Sopenharmony_ci *
1238d5ac70f0Sopenharmony_ci * \sa snd_seq_get_output_buffer_size()
1239d5ac70f0Sopenharmony_ci */
1240d5ac70f0Sopenharmony_ciint snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
1241d5ac70f0Sopenharmony_ci{
1242d5ac70f0Sopenharmony_ci	assert(seq && seq->obuf);
1243d5ac70f0Sopenharmony_ci	assert(size >= sizeof(snd_seq_event_t));
1244d5ac70f0Sopenharmony_ci	snd_seq_drop_output(seq);
1245d5ac70f0Sopenharmony_ci	if (size != seq->obufsize) {
1246d5ac70f0Sopenharmony_ci		char *newbuf;
1247d5ac70f0Sopenharmony_ci		newbuf = calloc(1, size);
1248d5ac70f0Sopenharmony_ci		if (newbuf == NULL)
1249d5ac70f0Sopenharmony_ci			return -ENOMEM;
1250d5ac70f0Sopenharmony_ci		free(seq->obuf);
1251d5ac70f0Sopenharmony_ci		seq->obuf = newbuf;
1252d5ac70f0Sopenharmony_ci		seq->obufsize = size;
1253d5ac70f0Sopenharmony_ci	}
1254d5ac70f0Sopenharmony_ci	return 0;
1255d5ac70f0Sopenharmony_ci}
1256d5ac70f0Sopenharmony_ci
1257d5ac70f0Sopenharmony_ci/**
1258d5ac70f0Sopenharmony_ci * \brief Resize the input buffer
1259d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1260d5ac70f0Sopenharmony_ci * \param size the size of input buffer to be changed in bytes
1261d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1262d5ac70f0Sopenharmony_ci *
1263d5ac70f0Sopenharmony_ci * Changes the size of input buffer.
1264d5ac70f0Sopenharmony_ci *
1265d5ac70f0Sopenharmony_ci * \sa snd_seq_get_input_buffer_size()
1266d5ac70f0Sopenharmony_ci */
1267d5ac70f0Sopenharmony_ciint snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
1268d5ac70f0Sopenharmony_ci{
1269d5ac70f0Sopenharmony_ci	size_t packet_size;
1270d5ac70f0Sopenharmony_ci
1271d5ac70f0Sopenharmony_ci	assert(seq && seq->ibuf);
1272d5ac70f0Sopenharmony_ci	packet_size = get_packet_size(seq);
1273d5ac70f0Sopenharmony_ci	assert(size >= packet_size);
1274d5ac70f0Sopenharmony_ci	snd_seq_drop_input(seq);
1275d5ac70f0Sopenharmony_ci	size = (size + packet_size - 1) / packet_size;
1276d5ac70f0Sopenharmony_ci	if (size != seq->ibufsize) {
1277d5ac70f0Sopenharmony_ci		char *newbuf;
1278d5ac70f0Sopenharmony_ci		/* use ump event size for avoiding reallocation at switching */
1279d5ac70f0Sopenharmony_ci		newbuf = calloc(sizeof(snd_seq_ump_event_t), size);
1280d5ac70f0Sopenharmony_ci		if (newbuf == NULL)
1281d5ac70f0Sopenharmony_ci			return -ENOMEM;
1282d5ac70f0Sopenharmony_ci		free(seq->ibuf);
1283d5ac70f0Sopenharmony_ci		seq->ibuf = newbuf;
1284d5ac70f0Sopenharmony_ci		seq->ibufsize = size;
1285d5ac70f0Sopenharmony_ci	}
1286d5ac70f0Sopenharmony_ci	return 0;
1287d5ac70f0Sopenharmony_ci}
1288d5ac70f0Sopenharmony_ci
1289d5ac70f0Sopenharmony_ci
1290d5ac70f0Sopenharmony_ci/**
1291d5ac70f0Sopenharmony_ci * \brief Get size of #snd_seq_system_info_t
1292d5ac70f0Sopenharmony_ci * \return size in bytes
1293d5ac70f0Sopenharmony_ci */
1294d5ac70f0Sopenharmony_cisize_t snd_seq_system_info_sizeof()
1295d5ac70f0Sopenharmony_ci{
1296d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_system_info_t);
1297d5ac70f0Sopenharmony_ci}
1298d5ac70f0Sopenharmony_ci
1299d5ac70f0Sopenharmony_ci/**
1300d5ac70f0Sopenharmony_ci * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
1301d5ac70f0Sopenharmony_ci * \param ptr returned pointer
1302d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
1303d5ac70f0Sopenharmony_ci */
1304d5ac70f0Sopenharmony_ciint snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
1305d5ac70f0Sopenharmony_ci{
1306d5ac70f0Sopenharmony_ci	assert(ptr);
1307d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_system_info_t));
1308d5ac70f0Sopenharmony_ci	if (!*ptr)
1309d5ac70f0Sopenharmony_ci		return -ENOMEM;
1310d5ac70f0Sopenharmony_ci	return 0;
1311d5ac70f0Sopenharmony_ci}
1312d5ac70f0Sopenharmony_ci
1313d5ac70f0Sopenharmony_ci/**
1314d5ac70f0Sopenharmony_ci * \brief Frees a previously allocated #snd_seq_system_info_t
1315d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
1316d5ac70f0Sopenharmony_ci */
1317d5ac70f0Sopenharmony_civoid snd_seq_system_info_free(snd_seq_system_info_t *obj)
1318d5ac70f0Sopenharmony_ci{
1319d5ac70f0Sopenharmony_ci	free(obj);
1320d5ac70f0Sopenharmony_ci}
1321d5ac70f0Sopenharmony_ci
1322d5ac70f0Sopenharmony_ci/**
1323d5ac70f0Sopenharmony_ci * \brief Copy one #snd_seq_system_info_t to another
1324d5ac70f0Sopenharmony_ci * \param dst pointer to destination
1325d5ac70f0Sopenharmony_ci * \param src pointer to source
1326d5ac70f0Sopenharmony_ci */
1327d5ac70f0Sopenharmony_civoid snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
1328d5ac70f0Sopenharmony_ci{
1329d5ac70f0Sopenharmony_ci	assert(dst && src);
1330d5ac70f0Sopenharmony_ci	*dst = *src;
1331d5ac70f0Sopenharmony_ci}
1332d5ac70f0Sopenharmony_ci
1333d5ac70f0Sopenharmony_ci
1334d5ac70f0Sopenharmony_ci/**
1335d5ac70f0Sopenharmony_ci * \brief Get maximum number of queues
1336d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1337d5ac70f0Sopenharmony_ci * \return maximum number of queues
1338d5ac70f0Sopenharmony_ci *
1339d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1340d5ac70f0Sopenharmony_ci */
1341d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
1342d5ac70f0Sopenharmony_ci{
1343d5ac70f0Sopenharmony_ci	assert(info);
1344d5ac70f0Sopenharmony_ci	return info->queues;
1345d5ac70f0Sopenharmony_ci}
1346d5ac70f0Sopenharmony_ci
1347d5ac70f0Sopenharmony_ci/**
1348d5ac70f0Sopenharmony_ci * \brief Get maximum number of clients
1349d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1350d5ac70f0Sopenharmony_ci * \return maximum number of clients
1351d5ac70f0Sopenharmony_ci *
1352d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1353d5ac70f0Sopenharmony_ci */
1354d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
1355d5ac70f0Sopenharmony_ci{
1356d5ac70f0Sopenharmony_ci	assert(info);
1357d5ac70f0Sopenharmony_ci	return info->clients;
1358d5ac70f0Sopenharmony_ci}
1359d5ac70f0Sopenharmony_ci
1360d5ac70f0Sopenharmony_ci/**
1361d5ac70f0Sopenharmony_ci * \brief Get maximum number of ports
1362d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1363d5ac70f0Sopenharmony_ci * \return maximum number of ports
1364d5ac70f0Sopenharmony_ci *
1365d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1366d5ac70f0Sopenharmony_ci */
1367d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
1368d5ac70f0Sopenharmony_ci{
1369d5ac70f0Sopenharmony_ci	assert(info);
1370d5ac70f0Sopenharmony_ci	return info->ports;
1371d5ac70f0Sopenharmony_ci}
1372d5ac70f0Sopenharmony_ci
1373d5ac70f0Sopenharmony_ci/**
1374d5ac70f0Sopenharmony_ci * \brief Get maximum number of channels
1375d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1376d5ac70f0Sopenharmony_ci * \return maximum number of channels
1377d5ac70f0Sopenharmony_ci *
1378d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1379d5ac70f0Sopenharmony_ci */
1380d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
1381d5ac70f0Sopenharmony_ci{
1382d5ac70f0Sopenharmony_ci	assert(info);
1383d5ac70f0Sopenharmony_ci	return info->channels;
1384d5ac70f0Sopenharmony_ci}
1385d5ac70f0Sopenharmony_ci
1386d5ac70f0Sopenharmony_ci/**
1387d5ac70f0Sopenharmony_ci * \brief Get the current number of clients
1388d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1389d5ac70f0Sopenharmony_ci * \return current number of clients
1390d5ac70f0Sopenharmony_ci *
1391d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1392d5ac70f0Sopenharmony_ci */
1393d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
1394d5ac70f0Sopenharmony_ci{
1395d5ac70f0Sopenharmony_ci	assert(info);
1396d5ac70f0Sopenharmony_ci	return info->cur_clients;
1397d5ac70f0Sopenharmony_ci}
1398d5ac70f0Sopenharmony_ci
1399d5ac70f0Sopenharmony_ci/**
1400d5ac70f0Sopenharmony_ci * \brief Get the current number of queues
1401d5ac70f0Sopenharmony_ci * \param info #snd_seq_system_info_t container
1402d5ac70f0Sopenharmony_ci * \return current number of queues
1403d5ac70f0Sopenharmony_ci *
1404d5ac70f0Sopenharmony_ci * \sa snd_seq_system_info()
1405d5ac70f0Sopenharmony_ci */
1406d5ac70f0Sopenharmony_ciint snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
1407d5ac70f0Sopenharmony_ci{
1408d5ac70f0Sopenharmony_ci	assert(info);
1409d5ac70f0Sopenharmony_ci	return info->cur_queues;
1410d5ac70f0Sopenharmony_ci}
1411d5ac70f0Sopenharmony_ci
1412d5ac70f0Sopenharmony_ci/**
1413d5ac70f0Sopenharmony_ci * \brief obtain the sequencer system information
1414d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1415d5ac70f0Sopenharmony_ci * \param info the pointer to be stored
1416d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1417d5ac70f0Sopenharmony_ci *
1418d5ac70f0Sopenharmony_ci * Stores the global system information of ALSA sequencer system.
1419d5ac70f0Sopenharmony_ci * The returned data contains
1420d5ac70f0Sopenharmony_ci * the maximum available numbers of queues, clients, ports and channels.
1421d5ac70f0Sopenharmony_ci */
1422d5ac70f0Sopenharmony_ciint snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
1423d5ac70f0Sopenharmony_ci{
1424d5ac70f0Sopenharmony_ci	assert(seq && info);
1425d5ac70f0Sopenharmony_ci	return seq->ops->system_info(seq, info);
1426d5ac70f0Sopenharmony_ci}
1427d5ac70f0Sopenharmony_ci
1428d5ac70f0Sopenharmony_ci
1429d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
1430d5ac70f0Sopenharmony_ci
1431d5ac70f0Sopenharmony_ci/**
1432d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_client_info_t
1433d5ac70f0Sopenharmony_ci * \return size in bytes
1434d5ac70f0Sopenharmony_ci */
1435d5ac70f0Sopenharmony_cisize_t snd_seq_client_info_sizeof()
1436d5ac70f0Sopenharmony_ci{
1437d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_client_info_t);
1438d5ac70f0Sopenharmony_ci}
1439d5ac70f0Sopenharmony_ci
1440d5ac70f0Sopenharmony_ci/**
1441d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_client_info_t using standard malloc
1442d5ac70f0Sopenharmony_ci * \param ptr returned pointer
1443d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
1444d5ac70f0Sopenharmony_ci */
1445d5ac70f0Sopenharmony_ciint snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
1446d5ac70f0Sopenharmony_ci{
1447d5ac70f0Sopenharmony_ci	assert(ptr);
1448d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_client_info_t));
1449d5ac70f0Sopenharmony_ci	if (!*ptr)
1450d5ac70f0Sopenharmony_ci		return -ENOMEM;
1451d5ac70f0Sopenharmony_ci	return 0;
1452d5ac70f0Sopenharmony_ci}
1453d5ac70f0Sopenharmony_ci
1454d5ac70f0Sopenharmony_ci/**
1455d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_client_info_t
1456d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
1457d5ac70f0Sopenharmony_ci */
1458d5ac70f0Sopenharmony_civoid snd_seq_client_info_free(snd_seq_client_info_t *obj)
1459d5ac70f0Sopenharmony_ci{
1460d5ac70f0Sopenharmony_ci	free(obj);
1461d5ac70f0Sopenharmony_ci}
1462d5ac70f0Sopenharmony_ci
1463d5ac70f0Sopenharmony_ci/**
1464d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_client_info_t to another
1465d5ac70f0Sopenharmony_ci * \param dst pointer to destination
1466d5ac70f0Sopenharmony_ci * \param src pointer to source
1467d5ac70f0Sopenharmony_ci */
1468d5ac70f0Sopenharmony_civoid snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
1469d5ac70f0Sopenharmony_ci{
1470d5ac70f0Sopenharmony_ci	assert(dst && src);
1471d5ac70f0Sopenharmony_ci	*dst = *src;
1472d5ac70f0Sopenharmony_ci}
1473d5ac70f0Sopenharmony_ci
1474d5ac70f0Sopenharmony_ci
1475d5ac70f0Sopenharmony_ci/**
1476d5ac70f0Sopenharmony_ci * \brief Get client id of a client_info container
1477d5ac70f0Sopenharmony_ci * \param info client_info container
1478d5ac70f0Sopenharmony_ci * \return client id
1479d5ac70f0Sopenharmony_ci *
1480d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
1481d5ac70f0Sopenharmony_ci */
1482d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
1483d5ac70f0Sopenharmony_ci{
1484d5ac70f0Sopenharmony_ci	assert(info);
1485d5ac70f0Sopenharmony_ci	return info->client;
1486d5ac70f0Sopenharmony_ci}
1487d5ac70f0Sopenharmony_ci
1488d5ac70f0Sopenharmony_ci/**
1489d5ac70f0Sopenharmony_ci * \brief Get client type of a client_info container
1490d5ac70f0Sopenharmony_ci * \param info client_info container
1491d5ac70f0Sopenharmony_ci * \return client type
1492d5ac70f0Sopenharmony_ci *
1493d5ac70f0Sopenharmony_ci * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
1494d5ac70f0Sopenharmony_ci * for kernel or user client respectively.
1495d5ac70f0Sopenharmony_ci *
1496d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1497d5ac70f0Sopenharmony_ci */
1498d5ac70f0Sopenharmony_cisnd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
1499d5ac70f0Sopenharmony_ci{
1500d5ac70f0Sopenharmony_ci	assert(info);
1501d5ac70f0Sopenharmony_ci	return info->type;
1502d5ac70f0Sopenharmony_ci}
1503d5ac70f0Sopenharmony_ci
1504d5ac70f0Sopenharmony_ci/**
1505d5ac70f0Sopenharmony_ci * \brief Get the name of a client_info container
1506d5ac70f0Sopenharmony_ci * \param info client_info container
1507d5ac70f0Sopenharmony_ci * \return name string
1508d5ac70f0Sopenharmony_ci *
1509d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
1510d5ac70f0Sopenharmony_ci */
1511d5ac70f0Sopenharmony_ciconst char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
1512d5ac70f0Sopenharmony_ci{
1513d5ac70f0Sopenharmony_ci	assert(info);
1514d5ac70f0Sopenharmony_ci	return info->name;
1515d5ac70f0Sopenharmony_ci}
1516d5ac70f0Sopenharmony_ci
1517d5ac70f0Sopenharmony_ci/**
1518d5ac70f0Sopenharmony_ci * \brief Get the broadcast filter usage of a client_info container
1519d5ac70f0Sopenharmony_ci * \param info client_info container
1520d5ac70f0Sopenharmony_ci * \return 1 if broadcast is accepted
1521d5ac70f0Sopenharmony_ci *
1522d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
1523d5ac70f0Sopenharmony_ci */
1524d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
1525d5ac70f0Sopenharmony_ci{
1526d5ac70f0Sopenharmony_ci	assert(info);
1527d5ac70f0Sopenharmony_ci	return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
1528d5ac70f0Sopenharmony_ci}
1529d5ac70f0Sopenharmony_ci
1530d5ac70f0Sopenharmony_ci/**
1531d5ac70f0Sopenharmony_ci * \brief Get the error-bounce usage of a client_info container
1532d5ac70f0Sopenharmony_ci * \param info client_info container
1533d5ac70f0Sopenharmony_ci * \return 1 if error-bounce is enabled
1534d5ac70f0Sopenharmony_ci *
1535d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
1536d5ac70f0Sopenharmony_ci */
1537d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
1538d5ac70f0Sopenharmony_ci{
1539d5ac70f0Sopenharmony_ci	assert(info);
1540d5ac70f0Sopenharmony_ci	return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
1541d5ac70f0Sopenharmony_ci}
1542d5ac70f0Sopenharmony_ci
1543d5ac70f0Sopenharmony_ci/**
1544d5ac70f0Sopenharmony_ci * \brief Get the sound card number.
1545d5ac70f0Sopenharmony_ci * \param info client_info container
1546d5ac70f0Sopenharmony_ci * \return card number or -1 if value is not available.
1547d5ac70f0Sopenharmony_ci *
1548d5ac70f0Sopenharmony_ci * Only available for #SND_SEQ_KERNEL_CLIENT clients.
1549d5ac70f0Sopenharmony_ci *
1550d5ac70f0Sopenharmony_ci * The card number can be used to query state about the hardware
1551d5ac70f0Sopenharmony_ci * device providing this client, by concatenating <code>"hw:CARD="</code>
1552d5ac70f0Sopenharmony_ci * with the card number and using it as the <code>name</code> parameter
1553d5ac70f0Sopenharmony_ci * to #snd_ctl_open().
1554d5ac70f0Sopenharmony_ci *
1555d5ac70f0Sopenharmony_ci * \note
1556d5ac70f0Sopenharmony_ci * The return value of -1 is returned for two different conditions: when the
1557d5ac70f0Sopenharmony_ci * running kernel does not support this operation, and when the client
1558d5ac70f0Sopenharmony_ci * does not have a hardware card attached. See
1559d5ac70f0Sopenharmony_ci * #snd_seq_client_info_get_pid() for a way to determine if the
1560d5ac70f0Sopenharmony_ci * currently running kernel has support for this operation.
1561d5ac70f0Sopenharmony_ci *
1562d5ac70f0Sopenharmony_ci * \sa snd_seq_client_info_get_pid(),
1563d5ac70f0Sopenharmony_ci *     snd_card_get_name(),
1564d5ac70f0Sopenharmony_ci *     snd_card_get_longname(),
1565d5ac70f0Sopenharmony_ci *     snd_ctl_open(),
1566d5ac70f0Sopenharmony_ci *     snd_ctl_card_info()
1567d5ac70f0Sopenharmony_ci */
1568d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
1569d5ac70f0Sopenharmony_ci{
1570d5ac70f0Sopenharmony_ci	assert(info);
1571d5ac70f0Sopenharmony_ci	return info->card;
1572d5ac70f0Sopenharmony_ci}
1573d5ac70f0Sopenharmony_ci
1574d5ac70f0Sopenharmony_ci/**
1575d5ac70f0Sopenharmony_ci * \brief Get the owning PID.
1576d5ac70f0Sopenharmony_ci * \param info client_info container
1577d5ac70f0Sopenharmony_ci * \return pid or -1 if value is not available.
1578d5ac70f0Sopenharmony_ci *
1579d5ac70f0Sopenharmony_ci * Only available for #SND_SEQ_USER_CLIENT clients.
1580d5ac70f0Sopenharmony_ci *
1581d5ac70f0Sopenharmony_ci * \note
1582d5ac70f0Sopenharmony_ci * The functionality for getting a client's PID and getting a
1583d5ac70f0Sopenharmony_ci * client's card was added to the kernel at the same time, so you can
1584d5ac70f0Sopenharmony_ci * use this function to determine if the running kernel
1585d5ac70f0Sopenharmony_ci * supports reporting these values. If your own client has a valid
1586d5ac70f0Sopenharmony_ci * PID as reported by this function, then the running kernel supports
1587d5ac70f0Sopenharmony_ci * both #snd_seq_client_info_get_card() and #snd_seq_client_info_get_pid().
1588d5ac70f0Sopenharmony_ci *
1589d5ac70f0Sopenharmony_ci * \note
1590d5ac70f0Sopenharmony_ci * Example code for determining kernel support:
1591d5ac70f0Sopenharmony_ci * \code
1592d5ac70f0Sopenharmony_ci *   int is_get_card_or_pid_supported(snd_seq_t *seq)
1593d5ac70f0Sopenharmony_ci *   {
1594d5ac70f0Sopenharmony_ci *   	snd_seq_client_info_t *my_client_info;
1595d5ac70f0Sopenharmony_ci *   	snd_seq_client_info_alloca(&my_client_info);
1596d5ac70f0Sopenharmony_ci *   	snd_seq_get_client_info(seq, my_client_info);
1597d5ac70f0Sopenharmony_ci *   	return snd_seq_client_info_get_pid(my_client_info) != -1;
1598d5ac70f0Sopenharmony_ci *   }
1599d5ac70f0Sopenharmony_ci * \endcode
1600d5ac70f0Sopenharmony_ci *
1601d5ac70f0Sopenharmony_ci * \sa snd_seq_client_info_get_card()
1602d5ac70f0Sopenharmony_ci */
1603d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
1604d5ac70f0Sopenharmony_ci{
1605d5ac70f0Sopenharmony_ci	assert(info);
1606d5ac70f0Sopenharmony_ci	return info->pid;
1607d5ac70f0Sopenharmony_ci}
1608d5ac70f0Sopenharmony_ci
1609d5ac70f0Sopenharmony_ci/**
1610d5ac70f0Sopenharmony_ci * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
1611d5ac70f0Sopenharmony_ci * \param info client_info container
1612d5ac70f0Sopenharmony_ci * \return NULL if no event filter, or pointer to event filter bitmap
1613d5ac70f0Sopenharmony_ci *
1614d5ac70f0Sopenharmony_ci * Use #snd_seq_client_info_event_filter_check() instead.
1615d5ac70f0Sopenharmony_ci *
1616d5ac70f0Sopenharmony_ci * \sa snd_seq_client_info_event_filter_add(),
1617d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_del(),
1618d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_check(),
1619d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_clear(),
1620d5ac70f0Sopenharmony_ci *     snd_seq_get_client_info()
1621d5ac70f0Sopenharmony_ci */
1622d5ac70f0Sopenharmony_ciconst unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
1623d5ac70f0Sopenharmony_ci{
1624d5ac70f0Sopenharmony_ci	assert(info);
1625d5ac70f0Sopenharmony_ci	if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
1626d5ac70f0Sopenharmony_ci		return info->event_filter;
1627d5ac70f0Sopenharmony_ci	else
1628d5ac70f0Sopenharmony_ci		return NULL;
1629d5ac70f0Sopenharmony_ci}
1630d5ac70f0Sopenharmony_ci
1631d5ac70f0Sopenharmony_ci/**
1632d5ac70f0Sopenharmony_ci * \brief Disable event filtering of a client_info container
1633d5ac70f0Sopenharmony_ci * \param info client_info container
1634d5ac70f0Sopenharmony_ci *
1635d5ac70f0Sopenharmony_ci * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
1636d5ac70f0Sopenharmony_ci * the event filtering flag of this client_info container.
1637d5ac70f0Sopenharmony_ci *
1638d5ac70f0Sopenharmony_ci * \sa snd_seq_client_info_event_filter_add(),
1639d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_del(),
1640d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_check(),
1641d5ac70f0Sopenharmony_ci *     snd_seq_get_client_info(),
1642d5ac70f0Sopenharmony_ci *     snd_seq_set_client_info()
1643d5ac70f0Sopenharmony_ci */
1644d5ac70f0Sopenharmony_civoid snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
1645d5ac70f0Sopenharmony_ci{
1646d5ac70f0Sopenharmony_ci       assert(info);
1647d5ac70f0Sopenharmony_ci       info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1648d5ac70f0Sopenharmony_ci       memset(info->event_filter, 0, sizeof(info->event_filter));
1649d5ac70f0Sopenharmony_ci}
1650d5ac70f0Sopenharmony_ci
1651d5ac70f0Sopenharmony_ci/**
1652d5ac70f0Sopenharmony_ci * \brief Add an event type to the event filtering of a client_info container
1653d5ac70f0Sopenharmony_ci * \param info client_info container
1654d5ac70f0Sopenharmony_ci * \param event_type event type to be added
1655d5ac70f0Sopenharmony_ci *
1656d5ac70f0Sopenharmony_ci * Set the event filtering flag of this client_info and add the specified event type to the
1657d5ac70f0Sopenharmony_ci * filter bitmap of this client_info container.
1658d5ac70f0Sopenharmony_ci *
1659d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(),
1660d5ac70f0Sopenharmony_ci *     snd_seq_set_client_info(),
1661d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_del(),
1662d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_check(),
1663d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_clear()
1664d5ac70f0Sopenharmony_ci */
1665d5ac70f0Sopenharmony_civoid snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
1666d5ac70f0Sopenharmony_ci{
1667d5ac70f0Sopenharmony_ci       assert(info);
1668d5ac70f0Sopenharmony_ci       info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1669d5ac70f0Sopenharmony_ci       snd_seq_set_bit(event_type, info->event_filter);
1670d5ac70f0Sopenharmony_ci}
1671d5ac70f0Sopenharmony_ci
1672d5ac70f0Sopenharmony_ci/**
1673d5ac70f0Sopenharmony_ci * \brief Remove an event type from the event filtering of a client_info container
1674d5ac70f0Sopenharmony_ci * \param info client_info container
1675d5ac70f0Sopenharmony_ci * \param event_type event type to be removed
1676d5ac70f0Sopenharmony_ci *
1677d5ac70f0Sopenharmony_ci * Removes the specified event from the filter bitmap of this client_info container. It will
1678d5ac70f0Sopenharmony_ci * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
1679d5ac70f0Sopenharmony_ci *
1680d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(),
1681d5ac70f0Sopenharmony_ci *     snd_seq_set_client_info(),
1682d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_add(),
1683d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_check(),
1684d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_clear()
1685d5ac70f0Sopenharmony_ci */
1686d5ac70f0Sopenharmony_civoid snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
1687d5ac70f0Sopenharmony_ci{
1688d5ac70f0Sopenharmony_ci       assert(info);
1689d5ac70f0Sopenharmony_ci       snd_seq_unset_bit(event_type, info->event_filter);
1690d5ac70f0Sopenharmony_ci}
1691d5ac70f0Sopenharmony_ci
1692d5ac70f0Sopenharmony_ci/**
1693d5ac70f0Sopenharmony_ci * \brief Check if an event type is present in the event filtering of a client_info container
1694d5ac70f0Sopenharmony_ci * \param info client_info container
1695d5ac70f0Sopenharmony_ci * \param event_type event type to be checked
1696d5ac70f0Sopenharmony_ci * \return 1 if the event type is present, 0 otherwise
1697d5ac70f0Sopenharmony_ci *
1698d5ac70f0Sopenharmony_ci * Test if the event type is in the filter bitmap of this client_info container.
1699d5ac70f0Sopenharmony_ci *
1700d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(),
1701d5ac70f0Sopenharmony_ci *     snd_seq_set_client_info(),
1702d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_add(),
1703d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_del(),
1704d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_clear()
1705d5ac70f0Sopenharmony_ci */
1706d5ac70f0Sopenharmony_ciint snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
1707d5ac70f0Sopenharmony_ci{
1708d5ac70f0Sopenharmony_ci       assert(info);
1709d5ac70f0Sopenharmony_ci       return snd_seq_get_bit(event_type, info->event_filter);
1710d5ac70f0Sopenharmony_ci}
1711d5ac70f0Sopenharmony_ci
1712d5ac70f0Sopenharmony_ci/**
1713d5ac70f0Sopenharmony_ci * \brief Get the number of opened ports of a client_info container
1714d5ac70f0Sopenharmony_ci * \param info client_info container
1715d5ac70f0Sopenharmony_ci * \return number of opened ports
1716d5ac70f0Sopenharmony_ci *
1717d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1718d5ac70f0Sopenharmony_ci */
1719d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
1720d5ac70f0Sopenharmony_ci{
1721d5ac70f0Sopenharmony_ci	assert(info);
1722d5ac70f0Sopenharmony_ci	return info->num_ports;
1723d5ac70f0Sopenharmony_ci}
1724d5ac70f0Sopenharmony_ci
1725d5ac70f0Sopenharmony_ci/**
1726d5ac70f0Sopenharmony_ci * \brief Get the number of lost events of a client_info container
1727d5ac70f0Sopenharmony_ci * \param info client_info container
1728d5ac70f0Sopenharmony_ci * \return number of lost events
1729d5ac70f0Sopenharmony_ci *
1730d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1731d5ac70f0Sopenharmony_ci */
1732d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
1733d5ac70f0Sopenharmony_ci{
1734d5ac70f0Sopenharmony_ci	assert(info);
1735d5ac70f0Sopenharmony_ci	return info->event_lost;
1736d5ac70f0Sopenharmony_ci}
1737d5ac70f0Sopenharmony_ci
1738d5ac70f0Sopenharmony_ci/**
1739d5ac70f0Sopenharmony_ci * \brief Get the MIDI protocol version number of a client_info container
1740d5ac70f0Sopenharmony_ci * \param info client_info container
1741d5ac70f0Sopenharmony_ci * \return MIDI protocol version
1742d5ac70f0Sopenharmony_ci *
1743d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1744d5ac70f0Sopenharmony_ci */
1745d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_midi_version(const snd_seq_client_info_t *info)
1746d5ac70f0Sopenharmony_ci{
1747d5ac70f0Sopenharmony_ci	assert(info);
1748d5ac70f0Sopenharmony_ci	return info->midi_version;
1749d5ac70f0Sopenharmony_ci}
1750d5ac70f0Sopenharmony_ci
1751d5ac70f0Sopenharmony_ci/**
1752d5ac70f0Sopenharmony_ci * \brief Get the UMP group filter status
1753d5ac70f0Sopenharmony_ci * \param info client_info container
1754d5ac70f0Sopenharmony_ci * \param group 0-based group index
1755d5ac70f0Sopenharmony_ci * \return 0 if the group is filtered / disabled, 1 if it's processed
1756d5ac70f0Sopenharmony_ci *
1757d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1758d5ac70f0Sopenharmony_ci */
1759d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_ump_group_enabled(const snd_seq_client_info_t *info,
1760d5ac70f0Sopenharmony_ci					      int group)
1761d5ac70f0Sopenharmony_ci{
1762d5ac70f0Sopenharmony_ci	assert(info);
1763d5ac70f0Sopenharmony_ci	return !(info->group_filter & (1U << group));
1764d5ac70f0Sopenharmony_ci}
1765d5ac70f0Sopenharmony_ci
1766d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN
1767d5ac70f0Sopenharmony_ci#define UMP_GROUPLESS_FILTER	(1U << 0)
1768d5ac70f0Sopenharmony_ci#endif /* DOC_HIDDEN */
1769d5ac70f0Sopenharmony_ci
1770d5ac70f0Sopenharmony_ci/**
1771d5ac70f0Sopenharmony_ci * \brief Get the UMP groupless message handling status
1772d5ac70f0Sopenharmony_ci * \param info client_info container
1773d5ac70f0Sopenharmony_ci * \return 1 if UMP groupless messages is processed, 0 if filtered/disabled
1774d5ac70f0Sopenharmony_ci *
1775d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1776d5ac70f0Sopenharmony_ci */
1777d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_ump_groupless_enabled(const snd_seq_client_info_t *info)
1778d5ac70f0Sopenharmony_ci{
1779d5ac70f0Sopenharmony_ci	assert(info);
1780d5ac70f0Sopenharmony_ci	return !(info->group_filter & UMP_GROUPLESS_FILTER);
1781d5ac70f0Sopenharmony_ci}
1782d5ac70f0Sopenharmony_ci
1783d5ac70f0Sopenharmony_ci/**
1784d5ac70f0Sopenharmony_ci * \brief Get the automatic conversion mode for UMP
1785d5ac70f0Sopenharmony_ci * \param info client_info container
1786d5ac70f0Sopenharmony_ci * \return 1 if the conversion is enabled, 0 if not
1787d5ac70f0Sopenharmony_ci *
1788d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1789d5ac70f0Sopenharmony_ci */
1790d5ac70f0Sopenharmony_ciint snd_seq_client_info_get_ump_conversion(const snd_seq_client_info_t *info)
1791d5ac70f0Sopenharmony_ci{
1792d5ac70f0Sopenharmony_ci	assert(info);
1793d5ac70f0Sopenharmony_ci	return info->midi_version;
1794d5ac70f0Sopenharmony_ci}
1795d5ac70f0Sopenharmony_ci
1796d5ac70f0Sopenharmony_ci/**
1797d5ac70f0Sopenharmony_ci * \brief Set the client id of a client_info container
1798d5ac70f0Sopenharmony_ci * \param info client_info container
1799d5ac70f0Sopenharmony_ci * \param client client id
1800d5ac70f0Sopenharmony_ci *
1801d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
1802d5ac70f0Sopenharmony_ci */
1803d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
1804d5ac70f0Sopenharmony_ci{
1805d5ac70f0Sopenharmony_ci	assert(info);
1806d5ac70f0Sopenharmony_ci	info->client = client;
1807d5ac70f0Sopenharmony_ci}
1808d5ac70f0Sopenharmony_ci
1809d5ac70f0Sopenharmony_ci/**
1810d5ac70f0Sopenharmony_ci * \brief Set the name of a client_info container
1811d5ac70f0Sopenharmony_ci * \param info client_info container
1812d5ac70f0Sopenharmony_ci * \param name name string
1813d5ac70f0Sopenharmony_ci *
1814d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
1815d5ac70f0Sopenharmony_ci *     snd_seq_set_client_name()
1816d5ac70f0Sopenharmony_ci */
1817d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
1818d5ac70f0Sopenharmony_ci{
1819d5ac70f0Sopenharmony_ci	assert(info && name);
1820d5ac70f0Sopenharmony_ci	snd_strlcpy(info->name, name, sizeof(info->name));
1821d5ac70f0Sopenharmony_ci}
1822d5ac70f0Sopenharmony_ci
1823d5ac70f0Sopenharmony_ci/**
1824d5ac70f0Sopenharmony_ci * \brief Set the broadcast filter usage of a client_info container
1825d5ac70f0Sopenharmony_ci * \param info client_info container
1826d5ac70f0Sopenharmony_ci * \param val non-zero if broadcast is accepted
1827d5ac70f0Sopenharmony_ci *
1828d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
1829d5ac70f0Sopenharmony_ci */
1830d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
1831d5ac70f0Sopenharmony_ci{
1832d5ac70f0Sopenharmony_ci	assert(info);
1833d5ac70f0Sopenharmony_ci	if (val)
1834d5ac70f0Sopenharmony_ci		info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
1835d5ac70f0Sopenharmony_ci	else
1836d5ac70f0Sopenharmony_ci		info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
1837d5ac70f0Sopenharmony_ci}
1838d5ac70f0Sopenharmony_ci
1839d5ac70f0Sopenharmony_ci/**
1840d5ac70f0Sopenharmony_ci * \brief Set the MIDI protocol version of a client_info container
1841d5ac70f0Sopenharmony_ci * \param info client_info container
1842d5ac70f0Sopenharmony_ci * \param midi_version MIDI protocol version to set
1843d5ac70f0Sopenharmony_ci *
1844d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_get_midi_version()
1845d5ac70f0Sopenharmony_ci */
1846d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_midi_version(snd_seq_client_info_t *info, int midi_version)
1847d5ac70f0Sopenharmony_ci{
1848d5ac70f0Sopenharmony_ci	assert(info);
1849d5ac70f0Sopenharmony_ci	info->midi_version = midi_version;
1850d5ac70f0Sopenharmony_ci}
1851d5ac70f0Sopenharmony_ci
1852d5ac70f0Sopenharmony_ci/**
1853d5ac70f0Sopenharmony_ci * \brief Set the UMP group filter status
1854d5ac70f0Sopenharmony_ci * \param info client_info container
1855d5ac70f0Sopenharmony_ci * \param group 0-based group index
1856d5ac70f0Sopenharmony_ci * \param enable 0 to filter/disable the group, non-zero to enable
1857d5ac70f0Sopenharmony_ci *
1858d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info(), snd_seq_client_info_get_ump_group_enabled()
1859d5ac70f0Sopenharmony_ci */
1860d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_ump_group_enabled(snd_seq_client_info_t *info,
1861d5ac70f0Sopenharmony_ci					       int group, int enable)
1862d5ac70f0Sopenharmony_ci{
1863d5ac70f0Sopenharmony_ci	assert(info);
1864d5ac70f0Sopenharmony_ci	if (enable)
1865d5ac70f0Sopenharmony_ci		info->group_filter &= ~(1U << group);
1866d5ac70f0Sopenharmony_ci	else
1867d5ac70f0Sopenharmony_ci		info->group_filter |= (1U << group);
1868d5ac70f0Sopenharmony_ci}
1869d5ac70f0Sopenharmony_ci
1870d5ac70f0Sopenharmony_ci/**
1871d5ac70f0Sopenharmony_ci * \brief Enable/disable the UMP groupless message handling
1872d5ac70f0Sopenharmony_ci * \param info client_info container
1873d5ac70f0Sopenharmony_ci * \param enable enable the UMP groupless messages
1874d5ac70f0Sopenharmony_ci *
1875d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info(), snd_seq_client_info_get_ump_groupless_enabled()
1876d5ac70f0Sopenharmony_ci */
1877d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_ump_groupless_enabled(snd_seq_client_info_t *info,
1878d5ac70f0Sopenharmony_ci						   int enable)
1879d5ac70f0Sopenharmony_ci{
1880d5ac70f0Sopenharmony_ci	assert(info);
1881d5ac70f0Sopenharmony_ci	if (enable)
1882d5ac70f0Sopenharmony_ci		info->group_filter &= ~UMP_GROUPLESS_FILTER;
1883d5ac70f0Sopenharmony_ci	else
1884d5ac70f0Sopenharmony_ci		info->group_filter |= UMP_GROUPLESS_FILTER;
1885d5ac70f0Sopenharmony_ci}
1886d5ac70f0Sopenharmony_ci
1887d5ac70f0Sopenharmony_ci/**
1888d5ac70f0Sopenharmony_ci * \brief Set the automatic conversion mode for UMP
1889d5ac70f0Sopenharmony_ci * \param info client_info container
1890d5ac70f0Sopenharmony_ci * \param enable 0 or 1 for disabling/enabling the conversion
1891d5ac70f0Sopenharmony_ci *
1892d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info(), snd_seq_client_info_get_ump_conversion()
1893d5ac70f0Sopenharmony_ci */
1894d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_ump_conversion(snd_seq_client_info_t *info,
1895d5ac70f0Sopenharmony_ci					    int enable)
1896d5ac70f0Sopenharmony_ci{
1897d5ac70f0Sopenharmony_ci	assert(info);
1898d5ac70f0Sopenharmony_ci	if (enable)
1899d5ac70f0Sopenharmony_ci		info->filter &= ~SNDRV_SEQ_FILTER_NO_CONVERT;
1900d5ac70f0Sopenharmony_ci	else
1901d5ac70f0Sopenharmony_ci		info->filter |= SNDRV_SEQ_FILTER_NO_CONVERT;
1902d5ac70f0Sopenharmony_ci}
1903d5ac70f0Sopenharmony_ci
1904d5ac70f0Sopenharmony_ci/**
1905d5ac70f0Sopenharmony_ci * \brief Set the error-bounce usage of a client_info container
1906d5ac70f0Sopenharmony_ci * \param info client_info container
1907d5ac70f0Sopenharmony_ci * \param val non-zero if error is bounced
1908d5ac70f0Sopenharmony_ci *
1909d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
1910d5ac70f0Sopenharmony_ci */
1911d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
1912d5ac70f0Sopenharmony_ci{
1913d5ac70f0Sopenharmony_ci	assert(info);
1914d5ac70f0Sopenharmony_ci	if (val)
1915d5ac70f0Sopenharmony_ci		info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
1916d5ac70f0Sopenharmony_ci	else
1917d5ac70f0Sopenharmony_ci		info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
1918d5ac70f0Sopenharmony_ci}
1919d5ac70f0Sopenharmony_ci
1920d5ac70f0Sopenharmony_ci/**
1921d5ac70f0Sopenharmony_ci * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
1922d5ac70f0Sopenharmony_ci * \param info client_info container
1923d5ac70f0Sopenharmony_ci * \param filter event filter bitmap, pass NULL for no event filtering
1924d5ac70f0Sopenharmony_ci *
1925d5ac70f0Sopenharmony_ci * Use #snd_seq_client_info_event_filter_add instead.
1926d5ac70f0Sopenharmony_ci *
1927d5ac70f0Sopenharmony_ci * \sa snd_seq_client_info_event_filter_add(),
1928d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_del(),
1929d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_check(),
1930d5ac70f0Sopenharmony_ci *     snd_seq_client_info_event_filter_clear(),
1931d5ac70f0Sopenharmony_ci *     snd_seq_set_client_info()
1932d5ac70f0Sopenharmony_ci */
1933d5ac70f0Sopenharmony_civoid snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
1934d5ac70f0Sopenharmony_ci{
1935d5ac70f0Sopenharmony_ci	assert(info);
1936d5ac70f0Sopenharmony_ci	if (! filter)
1937d5ac70f0Sopenharmony_ci		info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1938d5ac70f0Sopenharmony_ci	else {
1939d5ac70f0Sopenharmony_ci		info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1940d5ac70f0Sopenharmony_ci		memcpy(info->event_filter, filter, sizeof(info->event_filter));
1941d5ac70f0Sopenharmony_ci	}
1942d5ac70f0Sopenharmony_ci}
1943d5ac70f0Sopenharmony_ci
1944d5ac70f0Sopenharmony_ci
1945d5ac70f0Sopenharmony_ci/**
1946d5ac70f0Sopenharmony_ci * \brief obtain the information of the given client
1947d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1948d5ac70f0Sopenharmony_ci * \param client client id
1949d5ac70f0Sopenharmony_ci * \param info the pointer to be stored
1950d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1951d5ac70f0Sopenharmony_ci *
1952d5ac70f0Sopenharmony_ci * Obtains the information of the client with a client id specified by
1953d5ac70f0Sopenharmony_ci * info argument.
1954d5ac70f0Sopenharmony_ci * The obtained information is written on info parameter.
1955d5ac70f0Sopenharmony_ci *
1956d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1957d5ac70f0Sopenharmony_ci */
1958d5ac70f0Sopenharmony_ciint snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
1959d5ac70f0Sopenharmony_ci{
1960d5ac70f0Sopenharmony_ci	assert(seq && info && client >= 0);
1961d5ac70f0Sopenharmony_ci	memset(info, 0, sizeof(snd_seq_client_info_t));
1962d5ac70f0Sopenharmony_ci	info->client = client;
1963d5ac70f0Sopenharmony_ci	return seq->ops->get_client_info(seq, info);
1964d5ac70f0Sopenharmony_ci}
1965d5ac70f0Sopenharmony_ci
1966d5ac70f0Sopenharmony_ci/**
1967d5ac70f0Sopenharmony_ci * \brief obtain the current client information
1968d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1969d5ac70f0Sopenharmony_ci * \param info the pointer to be stored
1970d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1971d5ac70f0Sopenharmony_ci *
1972d5ac70f0Sopenharmony_ci * Obtains the information of the current client stored on info.
1973d5ac70f0Sopenharmony_ci * client and type fields are ignored.
1974d5ac70f0Sopenharmony_ci *
1975d5ac70f0Sopenharmony_ci * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
1976d5ac70f0Sopenharmony_ci *     snd_seq_query_next_client()
1977d5ac70f0Sopenharmony_ci */
1978d5ac70f0Sopenharmony_ciint snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1979d5ac70f0Sopenharmony_ci{
1980d5ac70f0Sopenharmony_ci	return snd_seq_get_any_client_info(seq, seq->client, info);
1981d5ac70f0Sopenharmony_ci}
1982d5ac70f0Sopenharmony_ci
1983d5ac70f0Sopenharmony_ci/**
1984d5ac70f0Sopenharmony_ci * \brief set the current client information
1985d5ac70f0Sopenharmony_ci * \param seq sequencer handle
1986d5ac70f0Sopenharmony_ci * \param info the client info data to set
1987d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
1988d5ac70f0Sopenharmony_ci *
1989d5ac70f0Sopenharmony_ci * Obtains the information of the current client stored on info.
1990d5ac70f0Sopenharmony_ci * client and type fields are ignored.
1991d5ac70f0Sopenharmony_ci *
1992d5ac70f0Sopenharmony_ci * \sa snd_seq_get_client_info()
1993d5ac70f0Sopenharmony_ci */
1994d5ac70f0Sopenharmony_ciint snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1995d5ac70f0Sopenharmony_ci{
1996d5ac70f0Sopenharmony_ci	assert(seq && info);
1997d5ac70f0Sopenharmony_ci	info->client = seq->client;
1998d5ac70f0Sopenharmony_ci	info->type = USER_CLIENT;
1999d5ac70f0Sopenharmony_ci	return seq->ops->set_client_info(seq, info);
2000d5ac70f0Sopenharmony_ci}
2001d5ac70f0Sopenharmony_ci
2002d5ac70f0Sopenharmony_ci/**
2003d5ac70f0Sopenharmony_ci * \brief query the next client
2004d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2005d5ac70f0Sopenharmony_ci * \param info query pattern and result
2006d5ac70f0Sopenharmony_ci *
2007d5ac70f0Sopenharmony_ci * Queries the next client.
2008d5ac70f0Sopenharmony_ci * The search begins at the client with an id one greater than
2009d5ac70f0Sopenharmony_ci * client field in info.
2010d5ac70f0Sopenharmony_ci * If a client is found, its attributes are stored in info,
2011d5ac70f0Sopenharmony_ci * and zero is returned.
2012d5ac70f0Sopenharmony_ci * Otherwise returns a negative error code.
2013d5ac70f0Sopenharmony_ci *
2014d5ac70f0Sopenharmony_ci * \sa snd_seq_get_any_client_info()
2015d5ac70f0Sopenharmony_ci */
2016d5ac70f0Sopenharmony_ciint snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
2017d5ac70f0Sopenharmony_ci{
2018d5ac70f0Sopenharmony_ci	assert(seq && info);
2019d5ac70f0Sopenharmony_ci	return seq->ops->query_next_client(seq, info);
2020d5ac70f0Sopenharmony_ci}
2021d5ac70f0Sopenharmony_ci
2022d5ac70f0Sopenharmony_ci/**
2023d5ac70f0Sopenharmony_ci * \brief Get UMP Endpoint information
2024d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2025d5ac70f0Sopenharmony_ci * \param client client number to query
2026d5ac70f0Sopenharmony_ci * \param info the pointer to store snd_ump_endpoint_info_t data
2027d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2028d5ac70f0Sopenharmony_ci */
2029d5ac70f0Sopenharmony_ciint snd_seq_get_ump_endpoint_info(snd_seq_t *seq, int client, void *info)
2030d5ac70f0Sopenharmony_ci{
2031d5ac70f0Sopenharmony_ci	assert(seq && info);
2032d5ac70f0Sopenharmony_ci	return seq->ops->get_ump_info(seq, client,
2033d5ac70f0Sopenharmony_ci				      SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT,
2034d5ac70f0Sopenharmony_ci				      info);
2035d5ac70f0Sopenharmony_ci}
2036d5ac70f0Sopenharmony_ci
2037d5ac70f0Sopenharmony_ci/**
2038d5ac70f0Sopenharmony_ci * \brief Get UMP Block information
2039d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2040d5ac70f0Sopenharmony_ci * \param client sequencer client number to query
2041d5ac70f0Sopenharmony_ci * \param blk UMP block number (0-based) to query
2042d5ac70f0Sopenharmony_ci * \param info the pointer to store snd_ump_block_info_t data
2043d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2044d5ac70f0Sopenharmony_ci */
2045d5ac70f0Sopenharmony_ciint snd_seq_get_ump_block_info(snd_seq_t *seq, int client, int blk, void *info)
2046d5ac70f0Sopenharmony_ci{
2047d5ac70f0Sopenharmony_ci	assert(seq && info);
2048d5ac70f0Sopenharmony_ci	return seq->ops->get_ump_info(seq, client,
2049d5ac70f0Sopenharmony_ci				      SNDRV_SEQ_CLIENT_UMP_INFO_BLOCK + blk,
2050d5ac70f0Sopenharmony_ci				      info);
2051d5ac70f0Sopenharmony_ci}
2052d5ac70f0Sopenharmony_ci
2053d5ac70f0Sopenharmony_ci/**
2054d5ac70f0Sopenharmony_ci * \brief Set UMP Endpoint information to the current client
2055d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2056d5ac70f0Sopenharmony_ci * \param info the pointer to send snd_ump_endpoint_info_t data
2057d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2058d5ac70f0Sopenharmony_ci */
2059d5ac70f0Sopenharmony_ciint snd_seq_set_ump_endpoint_info(snd_seq_t *seq, const void *info)
2060d5ac70f0Sopenharmony_ci{
2061d5ac70f0Sopenharmony_ci	assert(seq && info);
2062d5ac70f0Sopenharmony_ci	return seq->ops->set_ump_info(seq,
2063d5ac70f0Sopenharmony_ci				      SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT,
2064d5ac70f0Sopenharmony_ci				      info);
2065d5ac70f0Sopenharmony_ci}
2066d5ac70f0Sopenharmony_ci
2067d5ac70f0Sopenharmony_ci/**
2068d5ac70f0Sopenharmony_ci * \brief Set UMP Block information to the current client
2069d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2070d5ac70f0Sopenharmony_ci * \param blk UMP block number (0-based) to send
2071d5ac70f0Sopenharmony_ci * \param info the pointer to send snd_ump_block_info_t data
2072d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2073d5ac70f0Sopenharmony_ci */
2074d5ac70f0Sopenharmony_ciint snd_seq_set_ump_block_info(snd_seq_t *seq, int blk, const void *info)
2075d5ac70f0Sopenharmony_ci{
2076d5ac70f0Sopenharmony_ci	assert(seq && info);
2077d5ac70f0Sopenharmony_ci	return seq->ops->set_ump_info(seq,
2078d5ac70f0Sopenharmony_ci				      SNDRV_SEQ_CLIENT_UMP_INFO_BLOCK + blk,
2079d5ac70f0Sopenharmony_ci				      info);
2080d5ac70f0Sopenharmony_ci}
2081d5ac70f0Sopenharmony_ci
2082d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
2083d5ac70f0Sopenharmony_ci
2084d5ac70f0Sopenharmony_ci
2085d5ac70f0Sopenharmony_ci/*
2086d5ac70f0Sopenharmony_ci * Port
2087d5ac70f0Sopenharmony_ci */
2088d5ac70f0Sopenharmony_ci
2089d5ac70f0Sopenharmony_ci/**
2090d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_port_info_t
2091d5ac70f0Sopenharmony_ci * \return size in bytes
2092d5ac70f0Sopenharmony_ci */
2093d5ac70f0Sopenharmony_cisize_t snd_seq_port_info_sizeof()
2094d5ac70f0Sopenharmony_ci{
2095d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_port_info_t);
2096d5ac70f0Sopenharmony_ci}
2097d5ac70f0Sopenharmony_ci
2098d5ac70f0Sopenharmony_ci/**
2099d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_port_info_t using standard malloc
2100d5ac70f0Sopenharmony_ci * \param ptr returned pointer
2101d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
2102d5ac70f0Sopenharmony_ci */
2103d5ac70f0Sopenharmony_ciint snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
2104d5ac70f0Sopenharmony_ci{
2105d5ac70f0Sopenharmony_ci	assert(ptr);
2106d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_port_info_t));
2107d5ac70f0Sopenharmony_ci	if (!*ptr)
2108d5ac70f0Sopenharmony_ci		return -ENOMEM;
2109d5ac70f0Sopenharmony_ci	return 0;
2110d5ac70f0Sopenharmony_ci}
2111d5ac70f0Sopenharmony_ci
2112d5ac70f0Sopenharmony_ci/**
2113d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_port_info_t
2114d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
2115d5ac70f0Sopenharmony_ci */
2116d5ac70f0Sopenharmony_civoid snd_seq_port_info_free(snd_seq_port_info_t *obj)
2117d5ac70f0Sopenharmony_ci{
2118d5ac70f0Sopenharmony_ci	free(obj);
2119d5ac70f0Sopenharmony_ci}
2120d5ac70f0Sopenharmony_ci
2121d5ac70f0Sopenharmony_ci/**
2122d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_port_info_t to another
2123d5ac70f0Sopenharmony_ci * \param dst pointer to destination
2124d5ac70f0Sopenharmony_ci * \param src pointer to source
2125d5ac70f0Sopenharmony_ci */
2126d5ac70f0Sopenharmony_civoid snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
2127d5ac70f0Sopenharmony_ci{
2128d5ac70f0Sopenharmony_ci	assert(dst && src);
2129d5ac70f0Sopenharmony_ci	*dst = *src;
2130d5ac70f0Sopenharmony_ci}
2131d5ac70f0Sopenharmony_ci
2132d5ac70f0Sopenharmony_ci
2133d5ac70f0Sopenharmony_ci/**
2134d5ac70f0Sopenharmony_ci * \brief Get client id of a port_info container
2135d5ac70f0Sopenharmony_ci * \param info port_info container
2136d5ac70f0Sopenharmony_ci * \return client id
2137d5ac70f0Sopenharmony_ci *
2138d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
2139d5ac70f0Sopenharmony_ci */
2140d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
2141d5ac70f0Sopenharmony_ci{
2142d5ac70f0Sopenharmony_ci	assert(info);
2143d5ac70f0Sopenharmony_ci	return info->addr.client;
2144d5ac70f0Sopenharmony_ci}
2145d5ac70f0Sopenharmony_ci
2146d5ac70f0Sopenharmony_ci/**
2147d5ac70f0Sopenharmony_ci * \brief Get port id of a port_info container
2148d5ac70f0Sopenharmony_ci * \param info port_info container
2149d5ac70f0Sopenharmony_ci * \return port id
2150d5ac70f0Sopenharmony_ci *
2151d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
2152d5ac70f0Sopenharmony_ci */
2153d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
2154d5ac70f0Sopenharmony_ci{
2155d5ac70f0Sopenharmony_ci	assert(info);
2156d5ac70f0Sopenharmony_ci	return info->addr.port;
2157d5ac70f0Sopenharmony_ci}
2158d5ac70f0Sopenharmony_ci
2159d5ac70f0Sopenharmony_ci/**
2160d5ac70f0Sopenharmony_ci * \brief Get client/port address of a port_info container
2161d5ac70f0Sopenharmony_ci * \param info port_info container
2162d5ac70f0Sopenharmony_ci * \return client/port address pointer
2163d5ac70f0Sopenharmony_ci *
2164d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
2165d5ac70f0Sopenharmony_ci */
2166d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
2167d5ac70f0Sopenharmony_ci{
2168d5ac70f0Sopenharmony_ci	assert(info);
2169d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *) &info->addr;
2170d5ac70f0Sopenharmony_ci}
2171d5ac70f0Sopenharmony_ci
2172d5ac70f0Sopenharmony_ci/**
2173d5ac70f0Sopenharmony_ci * \brief Get the name of a port_info container
2174d5ac70f0Sopenharmony_ci * \param info port_info container
2175d5ac70f0Sopenharmony_ci * \return name string
2176d5ac70f0Sopenharmony_ci *
2177d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
2178d5ac70f0Sopenharmony_ci */
2179d5ac70f0Sopenharmony_ciconst char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
2180d5ac70f0Sopenharmony_ci{
2181d5ac70f0Sopenharmony_ci	assert(info);
2182d5ac70f0Sopenharmony_ci	return info->name;
2183d5ac70f0Sopenharmony_ci}
2184d5ac70f0Sopenharmony_ci
2185d5ac70f0Sopenharmony_ci/**
2186d5ac70f0Sopenharmony_ci * \brief Get the capability bits of a port_info container
2187d5ac70f0Sopenharmony_ci * \param info port_info container
2188d5ac70f0Sopenharmony_ci * \return capability bits
2189d5ac70f0Sopenharmony_ci *
2190d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
2191d5ac70f0Sopenharmony_ci */
2192d5ac70f0Sopenharmony_ciunsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
2193d5ac70f0Sopenharmony_ci{
2194d5ac70f0Sopenharmony_ci	assert(info);
2195d5ac70f0Sopenharmony_ci	return info->capability;
2196d5ac70f0Sopenharmony_ci}
2197d5ac70f0Sopenharmony_ci
2198d5ac70f0Sopenharmony_ci/**
2199d5ac70f0Sopenharmony_ci * \brief Get the type bits of a port_info container
2200d5ac70f0Sopenharmony_ci * \param info port_info container
2201d5ac70f0Sopenharmony_ci * \return port type bits
2202d5ac70f0Sopenharmony_ci *
2203d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
2204d5ac70f0Sopenharmony_ci */
2205d5ac70f0Sopenharmony_ciunsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
2206d5ac70f0Sopenharmony_ci{
2207d5ac70f0Sopenharmony_ci	assert(info);
2208d5ac70f0Sopenharmony_ci	return info->type;
2209d5ac70f0Sopenharmony_ci}
2210d5ac70f0Sopenharmony_ci
2211d5ac70f0Sopenharmony_ci/**
2212d5ac70f0Sopenharmony_ci * \brief Get the number of read subscriptions of a port_info container
2213d5ac70f0Sopenharmony_ci * \param info port_info container
2214d5ac70f0Sopenharmony_ci * \return number of read subscriptions
2215d5ac70f0Sopenharmony_ci *
2216d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info()
2217d5ac70f0Sopenharmony_ci */
2218d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
2219d5ac70f0Sopenharmony_ci{
2220d5ac70f0Sopenharmony_ci	assert(info);
2221d5ac70f0Sopenharmony_ci	return info->read_use;
2222d5ac70f0Sopenharmony_ci}
2223d5ac70f0Sopenharmony_ci
2224d5ac70f0Sopenharmony_ci/**
2225d5ac70f0Sopenharmony_ci * \brief Get the number of write subscriptions of a port_info container
2226d5ac70f0Sopenharmony_ci * \param info port_info container
2227d5ac70f0Sopenharmony_ci * \return number of write subscriptions
2228d5ac70f0Sopenharmony_ci *
2229d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info()
2230d5ac70f0Sopenharmony_ci */
2231d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
2232d5ac70f0Sopenharmony_ci{
2233d5ac70f0Sopenharmony_ci	assert(info);
2234d5ac70f0Sopenharmony_ci	return info->write_use;
2235d5ac70f0Sopenharmony_ci}
2236d5ac70f0Sopenharmony_ci
2237d5ac70f0Sopenharmony_ci/**
2238d5ac70f0Sopenharmony_ci * \brief Get the midi channels of a port_info container
2239d5ac70f0Sopenharmony_ci * \param info port_info container
2240d5ac70f0Sopenharmony_ci * \return number of midi channels (default 0)
2241d5ac70f0Sopenharmony_ci *
2242d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
2243d5ac70f0Sopenharmony_ci */
2244d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
2245d5ac70f0Sopenharmony_ci{
2246d5ac70f0Sopenharmony_ci	assert(info);
2247d5ac70f0Sopenharmony_ci	return info->midi_channels;
2248d5ac70f0Sopenharmony_ci}
2249d5ac70f0Sopenharmony_ci
2250d5ac70f0Sopenharmony_ci/**
2251d5ac70f0Sopenharmony_ci * \brief Get the midi voices of a port_info container
2252d5ac70f0Sopenharmony_ci * \param info port_info container
2253d5ac70f0Sopenharmony_ci * \return number of midi voices (default 0)
2254d5ac70f0Sopenharmony_ci *
2255d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
2256d5ac70f0Sopenharmony_ci */
2257d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
2258d5ac70f0Sopenharmony_ci{
2259d5ac70f0Sopenharmony_ci	assert(info);
2260d5ac70f0Sopenharmony_ci	return info->midi_voices;
2261d5ac70f0Sopenharmony_ci}
2262d5ac70f0Sopenharmony_ci
2263d5ac70f0Sopenharmony_ci/**
2264d5ac70f0Sopenharmony_ci * \brief Get the synth voices of a port_info container
2265d5ac70f0Sopenharmony_ci * \param info port_info container
2266d5ac70f0Sopenharmony_ci * \return number of synth voices (default 0)
2267d5ac70f0Sopenharmony_ci *
2268d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
2269d5ac70f0Sopenharmony_ci */
2270d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
2271d5ac70f0Sopenharmony_ci{
2272d5ac70f0Sopenharmony_ci	assert(info);
2273d5ac70f0Sopenharmony_ci	return info->synth_voices;
2274d5ac70f0Sopenharmony_ci}
2275d5ac70f0Sopenharmony_ci
2276d5ac70f0Sopenharmony_ci/**
2277d5ac70f0Sopenharmony_ci * \brief Get the port-specified mode of a port_info container
2278d5ac70f0Sopenharmony_ci * \param info port_info container
2279d5ac70f0Sopenharmony_ci * \return 1 if port id is specified at creation
2280d5ac70f0Sopenharmony_ci *
2281d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
2282d5ac70f0Sopenharmony_ci */
2283d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
2284d5ac70f0Sopenharmony_ci{
2285d5ac70f0Sopenharmony_ci	assert(info);
2286d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
2287d5ac70f0Sopenharmony_ci}
2288d5ac70f0Sopenharmony_ci
2289d5ac70f0Sopenharmony_ci/**
2290d5ac70f0Sopenharmony_ci * \brief Get the time-stamping mode of the given port in a port_info container
2291d5ac70f0Sopenharmony_ci * \param info port_info container
2292d5ac70f0Sopenharmony_ci * \return 1 if the port updates timestamps of incoming events
2293d5ac70f0Sopenharmony_ci *
2294d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
2295d5ac70f0Sopenharmony_ci */
2296d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
2297d5ac70f0Sopenharmony_ci{
2298d5ac70f0Sopenharmony_ci	assert(info);
2299d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
2300d5ac70f0Sopenharmony_ci}
2301d5ac70f0Sopenharmony_ci
2302d5ac70f0Sopenharmony_ci/**
2303d5ac70f0Sopenharmony_ci * \brief Get whether the time-stamping of the given port is real-time mode
2304d5ac70f0Sopenharmony_ci * \param info port_info container
2305d5ac70f0Sopenharmony_ci * \return 1 if the time-stamping is in the real-time mode
2306d5ac70f0Sopenharmony_ci *
2307d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
2308d5ac70f0Sopenharmony_ci */
2309d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
2310d5ac70f0Sopenharmony_ci{
2311d5ac70f0Sopenharmony_ci	assert(info);
2312d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
2313d5ac70f0Sopenharmony_ci}
2314d5ac70f0Sopenharmony_ci
2315d5ac70f0Sopenharmony_ci/**
2316d5ac70f0Sopenharmony_ci * \brief Get the queue id to update timestamps
2317d5ac70f0Sopenharmony_ci * \param info port_info container
2318d5ac70f0Sopenharmony_ci * \return the queue id to get the timestamps
2319d5ac70f0Sopenharmony_ci *
2320d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
2321d5ac70f0Sopenharmony_ci */
2322d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
2323d5ac70f0Sopenharmony_ci{
2324d5ac70f0Sopenharmony_ci	assert(info);
2325d5ac70f0Sopenharmony_ci	return info->time_queue;
2326d5ac70f0Sopenharmony_ci}
2327d5ac70f0Sopenharmony_ci
2328d5ac70f0Sopenharmony_ci/**
2329d5ac70f0Sopenharmony_ci * \brief Get the direction of the port
2330d5ac70f0Sopenharmony_ci * \param info port_info container
2331d5ac70f0Sopenharmony_ci * \return the direction of the port
2332d5ac70f0Sopenharmony_ci *
2333d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_direction()
2334d5ac70f0Sopenharmony_ci */
2335d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_direction(const snd_seq_port_info_t *info)
2336d5ac70f0Sopenharmony_ci{
2337d5ac70f0Sopenharmony_ci	assert(info);
2338d5ac70f0Sopenharmony_ci	return info->direction;
2339d5ac70f0Sopenharmony_ci}
2340d5ac70f0Sopenharmony_ci
2341d5ac70f0Sopenharmony_ci/**
2342d5ac70f0Sopenharmony_ci * \brief Get the UMP Group assigned to the port
2343d5ac70f0Sopenharmony_ci * \param info port_info container
2344d5ac70f0Sopenharmony_ci * \return 0 for no conversion, or the (1-based) UMP Group number assigned to the port
2345d5ac70f0Sopenharmony_ci *
2346d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_set_ump_group()
2347d5ac70f0Sopenharmony_ci */
2348d5ac70f0Sopenharmony_ciint snd_seq_port_info_get_ump_group(const snd_seq_port_info_t *info)
2349d5ac70f0Sopenharmony_ci{
2350d5ac70f0Sopenharmony_ci	assert(info);
2351d5ac70f0Sopenharmony_ci	return info->ump_group;
2352d5ac70f0Sopenharmony_ci}
2353d5ac70f0Sopenharmony_ci
2354d5ac70f0Sopenharmony_ci/**
2355d5ac70f0Sopenharmony_ci * \brief Set the client id of a port_info container
2356d5ac70f0Sopenharmony_ci * \param info port_info container
2357d5ac70f0Sopenharmony_ci * \param client client id
2358d5ac70f0Sopenharmony_ci *
2359d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
2360d5ac70f0Sopenharmony_ci */
2361d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
2362d5ac70f0Sopenharmony_ci{
2363d5ac70f0Sopenharmony_ci	assert(info);
2364d5ac70f0Sopenharmony_ci	info->addr.client = client;
2365d5ac70f0Sopenharmony_ci}
2366d5ac70f0Sopenharmony_ci
2367d5ac70f0Sopenharmony_ci/**
2368d5ac70f0Sopenharmony_ci * \brief Set the port id of a port_info container
2369d5ac70f0Sopenharmony_ci * \param info port_info container
2370d5ac70f0Sopenharmony_ci * \param port port id
2371d5ac70f0Sopenharmony_ci *
2372d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
2373d5ac70f0Sopenharmony_ci */
2374d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
2375d5ac70f0Sopenharmony_ci{
2376d5ac70f0Sopenharmony_ci	assert(info);
2377d5ac70f0Sopenharmony_ci	info->addr.port = port;
2378d5ac70f0Sopenharmony_ci}
2379d5ac70f0Sopenharmony_ci
2380d5ac70f0Sopenharmony_ci/**
2381d5ac70f0Sopenharmony_ci * \brief Set the client/port address of a port_info container
2382d5ac70f0Sopenharmony_ci * \param info port_info container
2383d5ac70f0Sopenharmony_ci * \param addr client/port address
2384d5ac70f0Sopenharmony_ci *
2385d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
2386d5ac70f0Sopenharmony_ci */
2387d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
2388d5ac70f0Sopenharmony_ci{
2389d5ac70f0Sopenharmony_ci	assert(info);
2390d5ac70f0Sopenharmony_ci	info->addr = *(const struct sndrv_seq_addr *)addr;
2391d5ac70f0Sopenharmony_ci}
2392d5ac70f0Sopenharmony_ci
2393d5ac70f0Sopenharmony_ci/**
2394d5ac70f0Sopenharmony_ci * \brief Set the name of a port_info container
2395d5ac70f0Sopenharmony_ci * \param info port_info container
2396d5ac70f0Sopenharmony_ci * \param name name string
2397d5ac70f0Sopenharmony_ci *
2398d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
2399d5ac70f0Sopenharmony_ci */
2400d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
2401d5ac70f0Sopenharmony_ci{
2402d5ac70f0Sopenharmony_ci	assert(info && name);
2403d5ac70f0Sopenharmony_ci	snd_strlcpy(info->name, name, sizeof(info->name));
2404d5ac70f0Sopenharmony_ci}
2405d5ac70f0Sopenharmony_ci
2406d5ac70f0Sopenharmony_ci/**
2407d5ac70f0Sopenharmony_ci * \brief set the capability bits of a port_info container
2408d5ac70f0Sopenharmony_ci * \param info port_info container
2409d5ac70f0Sopenharmony_ci * \param capability capability bits
2410d5ac70f0Sopenharmony_ci *
2411d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
2412d5ac70f0Sopenharmony_ci */
2413d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
2414d5ac70f0Sopenharmony_ci{
2415d5ac70f0Sopenharmony_ci	assert(info);
2416d5ac70f0Sopenharmony_ci	info->capability = capability;
2417d5ac70f0Sopenharmony_ci}
2418d5ac70f0Sopenharmony_ci
2419d5ac70f0Sopenharmony_ci/**
2420d5ac70f0Sopenharmony_ci * \brief Get the type bits of a port_info container
2421d5ac70f0Sopenharmony_ci * \param info port_info container
2422d5ac70f0Sopenharmony_ci * \param type port type bits
2423d5ac70f0Sopenharmony_ci *
2424d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
2425d5ac70f0Sopenharmony_ci */
2426d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
2427d5ac70f0Sopenharmony_ci{
2428d5ac70f0Sopenharmony_ci	assert(info);
2429d5ac70f0Sopenharmony_ci	info->type = type;
2430d5ac70f0Sopenharmony_ci}
2431d5ac70f0Sopenharmony_ci
2432d5ac70f0Sopenharmony_ci/**
2433d5ac70f0Sopenharmony_ci * \brief set the midi channels of a port_info container
2434d5ac70f0Sopenharmony_ci * \param info port_info container
2435d5ac70f0Sopenharmony_ci * \param channels midi channels (default 0)
2436d5ac70f0Sopenharmony_ci *
2437d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
2438d5ac70f0Sopenharmony_ci */
2439d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
2440d5ac70f0Sopenharmony_ci{
2441d5ac70f0Sopenharmony_ci	assert(info);
2442d5ac70f0Sopenharmony_ci	info->midi_channels = channels;
2443d5ac70f0Sopenharmony_ci}
2444d5ac70f0Sopenharmony_ci
2445d5ac70f0Sopenharmony_ci/**
2446d5ac70f0Sopenharmony_ci * \brief set the midi voices of a port_info container
2447d5ac70f0Sopenharmony_ci * \param info port_info container
2448d5ac70f0Sopenharmony_ci * \param voices midi voices (default 0)
2449d5ac70f0Sopenharmony_ci *
2450d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
2451d5ac70f0Sopenharmony_ci */
2452d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
2453d5ac70f0Sopenharmony_ci{
2454d5ac70f0Sopenharmony_ci	assert(info);
2455d5ac70f0Sopenharmony_ci	info->midi_voices = voices;
2456d5ac70f0Sopenharmony_ci}
2457d5ac70f0Sopenharmony_ci
2458d5ac70f0Sopenharmony_ci/**
2459d5ac70f0Sopenharmony_ci * \brief set the synth voices of a port_info container
2460d5ac70f0Sopenharmony_ci * \param info port_info container
2461d5ac70f0Sopenharmony_ci * \param voices synth voices (default 0)
2462d5ac70f0Sopenharmony_ci *
2463d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
2464d5ac70f0Sopenharmony_ci */
2465d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
2466d5ac70f0Sopenharmony_ci{
2467d5ac70f0Sopenharmony_ci	assert(info);
2468d5ac70f0Sopenharmony_ci	info->synth_voices = voices;
2469d5ac70f0Sopenharmony_ci}
2470d5ac70f0Sopenharmony_ci
2471d5ac70f0Sopenharmony_ci/**
2472d5ac70f0Sopenharmony_ci * \brief Set the port-specified mode of a port_info container
2473d5ac70f0Sopenharmony_ci * \param info port_info container
2474d5ac70f0Sopenharmony_ci * \param val non-zero if specifying the port id at creation
2475d5ac70f0Sopenharmony_ci *
2476d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
2477d5ac70f0Sopenharmony_ci */
2478d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
2479d5ac70f0Sopenharmony_ci{
2480d5ac70f0Sopenharmony_ci	assert(info);
2481d5ac70f0Sopenharmony_ci	if (val)
2482d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2483d5ac70f0Sopenharmony_ci	else
2484d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2485d5ac70f0Sopenharmony_ci}
2486d5ac70f0Sopenharmony_ci
2487d5ac70f0Sopenharmony_ci/**
2488d5ac70f0Sopenharmony_ci * \brief Set the time-stamping mode of the given port
2489d5ac70f0Sopenharmony_ci * \param info port_info container
2490d5ac70f0Sopenharmony_ci * \param enable non-zero if updating the timestamps of incoming events
2491d5ac70f0Sopenharmony_ci *
2492d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
2493d5ac70f0Sopenharmony_ci */
2494d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
2495d5ac70f0Sopenharmony_ci{
2496d5ac70f0Sopenharmony_ci	assert(info);
2497d5ac70f0Sopenharmony_ci	if (enable)
2498d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2499d5ac70f0Sopenharmony_ci	else
2500d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2501d5ac70f0Sopenharmony_ci}
2502d5ac70f0Sopenharmony_ci
2503d5ac70f0Sopenharmony_ci/**
2504d5ac70f0Sopenharmony_ci * \brief Set whether the timestime is updated in the real-time mode
2505d5ac70f0Sopenharmony_ci * \param info port_info container
2506d5ac70f0Sopenharmony_ci * \param enable non-zero if updating the timestamps in real-time mode
2507d5ac70f0Sopenharmony_ci *
2508d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
2509d5ac70f0Sopenharmony_ci */
2510d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
2511d5ac70f0Sopenharmony_ci{
2512d5ac70f0Sopenharmony_ci	assert(info);
2513d5ac70f0Sopenharmony_ci	if (enable)
2514d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
2515d5ac70f0Sopenharmony_ci	else
2516d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
2517d5ac70f0Sopenharmony_ci}
2518d5ac70f0Sopenharmony_ci
2519d5ac70f0Sopenharmony_ci/**
2520d5ac70f0Sopenharmony_ci * \brief Set the queue id for timestamping
2521d5ac70f0Sopenharmony_ci * \param info port_info container
2522d5ac70f0Sopenharmony_ci * \param queue the queue id to get timestamps
2523d5ac70f0Sopenharmony_ci *
2524d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
2525d5ac70f0Sopenharmony_ci */
2526d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
2527d5ac70f0Sopenharmony_ci{
2528d5ac70f0Sopenharmony_ci	assert(info);
2529d5ac70f0Sopenharmony_ci	info->time_queue = queue;
2530d5ac70f0Sopenharmony_ci}
2531d5ac70f0Sopenharmony_ci
2532d5ac70f0Sopenharmony_ci/**
2533d5ac70f0Sopenharmony_ci * \brief Set the direction of the port
2534d5ac70f0Sopenharmony_ci * \param info port_info container
2535d5ac70f0Sopenharmony_ci * \param direction the port direction
2536d5ac70f0Sopenharmony_ci *
2537d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_direction()
2538d5ac70f0Sopenharmony_ci */
2539d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_direction(snd_seq_port_info_t *info, int direction)
2540d5ac70f0Sopenharmony_ci{
2541d5ac70f0Sopenharmony_ci	assert(info);
2542d5ac70f0Sopenharmony_ci	info->direction = direction;
2543d5ac70f0Sopenharmony_ci}
2544d5ac70f0Sopenharmony_ci
2545d5ac70f0Sopenharmony_ci/**
2546d5ac70f0Sopenharmony_ci * \brief Set the UMP Group assigned to the port
2547d5ac70f0Sopenharmony_ci * \param info port_info container
2548d5ac70f0Sopenharmony_ci * \param ump_group 0 for no conversion, or the (1-based) UMP Group number
2549d5ac70f0Sopenharmony_ci *
2550d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info(), snd_seq_port_info_get_ump_group()
2551d5ac70f0Sopenharmony_ci */
2552d5ac70f0Sopenharmony_civoid snd_seq_port_info_set_ump_group(snd_seq_port_info_t *info, int ump_group)
2553d5ac70f0Sopenharmony_ci{
2554d5ac70f0Sopenharmony_ci	assert(info);
2555d5ac70f0Sopenharmony_ci	info->ump_group = ump_group;
2556d5ac70f0Sopenharmony_ci}
2557d5ac70f0Sopenharmony_ci
2558d5ac70f0Sopenharmony_ci/**
2559d5ac70f0Sopenharmony_ci * \brief create a sequencer port on the current client
2560d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2561d5ac70f0Sopenharmony_ci * \param port port information for the new port
2562d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2563d5ac70f0Sopenharmony_ci *
2564d5ac70f0Sopenharmony_ci * Creates a sequencer port on the current client.
2565d5ac70f0Sopenharmony_ci * The attributes of created port is specified in \a info argument.
2566d5ac70f0Sopenharmony_ci *
2567d5ac70f0Sopenharmony_ci * The client field in \a info argument is overwritten with the current client id.
2568d5ac70f0Sopenharmony_ci * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
2569d5ac70f0Sopenharmony_ci * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
2570d5ac70f0Sopenharmony_ci *
2571d5ac70f0Sopenharmony_ci * Each port has the capability bit-masks to specify the access capability
2572d5ac70f0Sopenharmony_ci * of the port from other clients.
2573d5ac70f0Sopenharmony_ci * The capability bit flags are defined as follows:
2574d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_READ Readable from this port
2575d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
2576d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
2577d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
2578d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
2579d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
2580d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
2581d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
2582d5ac70f0Sopenharmony_ci *
2583d5ac70f0Sopenharmony_ci * Each port has also the type bitmasks defined as follows:
2584d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
2585d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
2586d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
2587d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
2588d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
2589d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
2590d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
2591d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
2592d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
2593d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
2594d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
2595d5ac70f0Sopenharmony_ci * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
2596d5ac70f0Sopenharmony_ci *
2597d5ac70f0Sopenharmony_ci * A port may contain specific midi channels, midi voices and synth voices.
2598d5ac70f0Sopenharmony_ci * These values could be zero as default.
2599d5ac70f0Sopenharmony_ci *
2600d5ac70f0Sopenharmony_ci * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
2601d5ac70f0Sopenharmony_ci *     snd_seq_create_simple_port()
2602d5ac70f0Sopenharmony_ci */
2603d5ac70f0Sopenharmony_ciint snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
2604d5ac70f0Sopenharmony_ci{
2605d5ac70f0Sopenharmony_ci	assert(seq && port);
2606d5ac70f0Sopenharmony_ci	port->addr.client = seq->client;
2607d5ac70f0Sopenharmony_ci	return seq->ops->create_port(seq, port);
2608d5ac70f0Sopenharmony_ci}
2609d5ac70f0Sopenharmony_ci
2610d5ac70f0Sopenharmony_ci/**
2611d5ac70f0Sopenharmony_ci * \brief delete a sequencer port on the current client
2612d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2613d5ac70f0Sopenharmony_ci * \param port port to be deleted
2614d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2615d5ac70f0Sopenharmony_ci *
2616d5ac70f0Sopenharmony_ci * Deletes the existing sequencer port on the current client.
2617d5ac70f0Sopenharmony_ci *
2618d5ac70f0Sopenharmony_ci * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
2619d5ac70f0Sopenharmony_ci */
2620d5ac70f0Sopenharmony_ciint snd_seq_delete_port(snd_seq_t *seq, int port)
2621d5ac70f0Sopenharmony_ci{
2622d5ac70f0Sopenharmony_ci	snd_seq_port_info_t pinfo;
2623d5ac70f0Sopenharmony_ci	assert(seq);
2624d5ac70f0Sopenharmony_ci	memset(&pinfo, 0, sizeof(pinfo));
2625d5ac70f0Sopenharmony_ci	pinfo.addr.client = seq->client;
2626d5ac70f0Sopenharmony_ci	pinfo.addr.port = port;
2627d5ac70f0Sopenharmony_ci	return seq->ops->delete_port(seq, &pinfo);
2628d5ac70f0Sopenharmony_ci}
2629d5ac70f0Sopenharmony_ci
2630d5ac70f0Sopenharmony_ci/**
2631d5ac70f0Sopenharmony_ci * \brief obtain the information of a port on an arbitrary client
2632d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2633d5ac70f0Sopenharmony_ci * \param client client id to get
2634d5ac70f0Sopenharmony_ci * \param port port id to get
2635d5ac70f0Sopenharmony_ci * \param info pointer information returns
2636d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2637d5ac70f0Sopenharmony_ci *
2638d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info()
2639d5ac70f0Sopenharmony_ci */
2640d5ac70f0Sopenharmony_ciint snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
2641d5ac70f0Sopenharmony_ci{
2642d5ac70f0Sopenharmony_ci	assert(seq && info && client >= 0 && port >= 0);
2643d5ac70f0Sopenharmony_ci	memset(info, 0, sizeof(snd_seq_port_info_t));
2644d5ac70f0Sopenharmony_ci	info->addr.client = client;
2645d5ac70f0Sopenharmony_ci	info->addr.port = port;
2646d5ac70f0Sopenharmony_ci	return seq->ops->get_port_info(seq, info);
2647d5ac70f0Sopenharmony_ci}
2648d5ac70f0Sopenharmony_ci
2649d5ac70f0Sopenharmony_ci/**
2650d5ac70f0Sopenharmony_ci * \brief obtain the information of a port on the current client
2651d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2652d5ac70f0Sopenharmony_ci * \param port port id to get
2653d5ac70f0Sopenharmony_ci * \param info pointer information returns
2654d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2655d5ac70f0Sopenharmony_ci *
2656d5ac70f0Sopenharmony_ci * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
2657d5ac70f0Sopenharmony_ci *     snd_seq_query_next_port()
2658d5ac70f0Sopenharmony_ci */
2659d5ac70f0Sopenharmony_ciint snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2660d5ac70f0Sopenharmony_ci{
2661d5ac70f0Sopenharmony_ci	return snd_seq_get_any_port_info(seq, seq->client, port, info);
2662d5ac70f0Sopenharmony_ci}
2663d5ac70f0Sopenharmony_ci
2664d5ac70f0Sopenharmony_ci/**
2665d5ac70f0Sopenharmony_ci * \brief set the information of a port on the current client
2666d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2667d5ac70f0Sopenharmony_ci * \param port port to be set
2668d5ac70f0Sopenharmony_ci * \param info port information to be set
2669d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2670d5ac70f0Sopenharmony_ci *
2671d5ac70f0Sopenharmony_ci * \sa snd_seq_set_port_info()
2672d5ac70f0Sopenharmony_ci */
2673d5ac70f0Sopenharmony_ciint snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2674d5ac70f0Sopenharmony_ci{
2675d5ac70f0Sopenharmony_ci	assert(seq && info && port >= 0);
2676d5ac70f0Sopenharmony_ci	info->addr.client = seq->client;
2677d5ac70f0Sopenharmony_ci	info->addr.port = port;
2678d5ac70f0Sopenharmony_ci	return seq->ops->set_port_info(seq, info);
2679d5ac70f0Sopenharmony_ci}
2680d5ac70f0Sopenharmony_ci
2681d5ac70f0Sopenharmony_ci/**
2682d5ac70f0Sopenharmony_ci * \brief query the next matching port
2683d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2684d5ac70f0Sopenharmony_ci * \param info query pattern and result
2685d5ac70f0Sopenharmony_ci
2686d5ac70f0Sopenharmony_ci * Queries the next matching port on the client specified in
2687d5ac70f0Sopenharmony_ci * \a info argument.
2688d5ac70f0Sopenharmony_ci * The search begins at the next port specified in
2689d5ac70f0Sopenharmony_ci * port field of \a info argument.
2690d5ac70f0Sopenharmony_ci * For finding the first port at a certain client, give -1.
2691d5ac70f0Sopenharmony_ci *
2692d5ac70f0Sopenharmony_ci * If a matching port is found, its attributes are stored on
2693d5ac70f0Sopenharmony_ci * \a info and function returns zero.
2694d5ac70f0Sopenharmony_ci * Otherwise, a negative error code is returned.
2695d5ac70f0Sopenharmony_ci *
2696d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_info()
2697d5ac70f0Sopenharmony_ci */
2698d5ac70f0Sopenharmony_ciint snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
2699d5ac70f0Sopenharmony_ci{
2700d5ac70f0Sopenharmony_ci	assert(seq && info);
2701d5ac70f0Sopenharmony_ci	return seq->ops->query_next_port(seq, info);
2702d5ac70f0Sopenharmony_ci}
2703d5ac70f0Sopenharmony_ci
2704d5ac70f0Sopenharmony_ci
2705d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
2706d5ac70f0Sopenharmony_ci
2707d5ac70f0Sopenharmony_ci/*
2708d5ac70f0Sopenharmony_ci * subscription
2709d5ac70f0Sopenharmony_ci */
2710d5ac70f0Sopenharmony_ci
2711d5ac70f0Sopenharmony_ci
2712d5ac70f0Sopenharmony_ci/**
2713d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_port_subscribe_t
2714d5ac70f0Sopenharmony_ci * \return size in bytes
2715d5ac70f0Sopenharmony_ci */
2716d5ac70f0Sopenharmony_cisize_t snd_seq_port_subscribe_sizeof()
2717d5ac70f0Sopenharmony_ci{
2718d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_port_subscribe_t);
2719d5ac70f0Sopenharmony_ci}
2720d5ac70f0Sopenharmony_ci
2721d5ac70f0Sopenharmony_ci/**
2722d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
2723d5ac70f0Sopenharmony_ci * \param ptr returned pointer
2724d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
2725d5ac70f0Sopenharmony_ci */
2726d5ac70f0Sopenharmony_ciint snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
2727d5ac70f0Sopenharmony_ci{
2728d5ac70f0Sopenharmony_ci	assert(ptr);
2729d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
2730d5ac70f0Sopenharmony_ci	if (!*ptr)
2731d5ac70f0Sopenharmony_ci		return -ENOMEM;
2732d5ac70f0Sopenharmony_ci	return 0;
2733d5ac70f0Sopenharmony_ci}
2734d5ac70f0Sopenharmony_ci
2735d5ac70f0Sopenharmony_ci/**
2736d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_port_subscribe_t
2737d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
2738d5ac70f0Sopenharmony_ci */
2739d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
2740d5ac70f0Sopenharmony_ci{
2741d5ac70f0Sopenharmony_ci	free(obj);
2742d5ac70f0Sopenharmony_ci}
2743d5ac70f0Sopenharmony_ci
2744d5ac70f0Sopenharmony_ci/**
2745d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_port_subscribe_t to another
2746d5ac70f0Sopenharmony_ci * \param dst pointer to destination
2747d5ac70f0Sopenharmony_ci * \param src pointer to source
2748d5ac70f0Sopenharmony_ci */
2749d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
2750d5ac70f0Sopenharmony_ci{
2751d5ac70f0Sopenharmony_ci	assert(dst && src);
2752d5ac70f0Sopenharmony_ci	*dst = *src;
2753d5ac70f0Sopenharmony_ci}
2754d5ac70f0Sopenharmony_ci
2755d5ac70f0Sopenharmony_ci
2756d5ac70f0Sopenharmony_ci/**
2757d5ac70f0Sopenharmony_ci * \brief Get sender address of a port_subscribe container
2758d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2759d5ac70f0Sopenharmony_ci *
2760d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
2761d5ac70f0Sopenharmony_ci */
2762d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
2763d5ac70f0Sopenharmony_ci{
2764d5ac70f0Sopenharmony_ci	assert(info);
2765d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *)&info->sender;
2766d5ac70f0Sopenharmony_ci}
2767d5ac70f0Sopenharmony_ci
2768d5ac70f0Sopenharmony_ci/**
2769d5ac70f0Sopenharmony_ci * \brief Get destination address of a port_subscribe container
2770d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2771d5ac70f0Sopenharmony_ci *
2772d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
2773d5ac70f0Sopenharmony_ci */
2774d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
2775d5ac70f0Sopenharmony_ci{
2776d5ac70f0Sopenharmony_ci	assert(info);
2777d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *)&info->dest;
2778d5ac70f0Sopenharmony_ci}
2779d5ac70f0Sopenharmony_ci
2780d5ac70f0Sopenharmony_ci/**
2781d5ac70f0Sopenharmony_ci * \brief Get the queue id of a port_subscribe container
2782d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2783d5ac70f0Sopenharmony_ci * \return queue id
2784d5ac70f0Sopenharmony_ci *
2785d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
2786d5ac70f0Sopenharmony_ci */
2787d5ac70f0Sopenharmony_ciint snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
2788d5ac70f0Sopenharmony_ci{
2789d5ac70f0Sopenharmony_ci	assert(info);
2790d5ac70f0Sopenharmony_ci	return info->queue;
2791d5ac70f0Sopenharmony_ci}
2792d5ac70f0Sopenharmony_ci
2793d5ac70f0Sopenharmony_ci/**
2794d5ac70f0Sopenharmony_ci * \brief Get the exclusive mode of a port_subscribe container
2795d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2796d5ac70f0Sopenharmony_ci * \return 1 if exclusive mode
2797d5ac70f0Sopenharmony_ci *
2798d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
2799d5ac70f0Sopenharmony_ci */
2800d5ac70f0Sopenharmony_ciint snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
2801d5ac70f0Sopenharmony_ci{
2802d5ac70f0Sopenharmony_ci	assert(info);
2803d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2804d5ac70f0Sopenharmony_ci}
2805d5ac70f0Sopenharmony_ci
2806d5ac70f0Sopenharmony_ci/**
2807d5ac70f0Sopenharmony_ci * \brief Get the time-update mode of a port_subscribe container
2808d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2809d5ac70f0Sopenharmony_ci * \return 1 if update timestamp
2810d5ac70f0Sopenharmony_ci *
2811d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
2812d5ac70f0Sopenharmony_ci */
2813d5ac70f0Sopenharmony_ciint snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
2814d5ac70f0Sopenharmony_ci{
2815d5ac70f0Sopenharmony_ci	assert(info);
2816d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2817d5ac70f0Sopenharmony_ci}
2818d5ac70f0Sopenharmony_ci
2819d5ac70f0Sopenharmony_ci/**
2820d5ac70f0Sopenharmony_ci * \brief Get the real-time update mode of a port_subscribe container
2821d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2822d5ac70f0Sopenharmony_ci * \return 1 if real-time update mode
2823d5ac70f0Sopenharmony_ci *
2824d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
2825d5ac70f0Sopenharmony_ci */
2826d5ac70f0Sopenharmony_ciint snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
2827d5ac70f0Sopenharmony_ci{
2828d5ac70f0Sopenharmony_ci	assert(info);
2829d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
2830d5ac70f0Sopenharmony_ci}
2831d5ac70f0Sopenharmony_ci
2832d5ac70f0Sopenharmony_ci/**
2833d5ac70f0Sopenharmony_ci * \brief Set sender address of a port_subscribe container
2834d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2835d5ac70f0Sopenharmony_ci * \param addr sender address
2836d5ac70f0Sopenharmony_ci *
2837d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
2838d5ac70f0Sopenharmony_ci */
2839d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2840d5ac70f0Sopenharmony_ci{
2841d5ac70f0Sopenharmony_ci	assert(info);
2842d5ac70f0Sopenharmony_ci	memcpy(&info->sender, addr, sizeof(*addr));
2843d5ac70f0Sopenharmony_ci}
2844d5ac70f0Sopenharmony_ci
2845d5ac70f0Sopenharmony_ci/**
2846d5ac70f0Sopenharmony_ci * \brief Set destination address of a port_subscribe container
2847d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2848d5ac70f0Sopenharmony_ci * \param addr destination address
2849d5ac70f0Sopenharmony_ci *
2850d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
2851d5ac70f0Sopenharmony_ci */
2852d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2853d5ac70f0Sopenharmony_ci{
2854d5ac70f0Sopenharmony_ci	assert(info);
2855d5ac70f0Sopenharmony_ci	memcpy(&info->dest, addr, sizeof(*addr));
2856d5ac70f0Sopenharmony_ci}
2857d5ac70f0Sopenharmony_ci
2858d5ac70f0Sopenharmony_ci/**
2859d5ac70f0Sopenharmony_ci * \brief Set the queue id of a port_subscribe container
2860d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2861d5ac70f0Sopenharmony_ci * \param q queue id
2862d5ac70f0Sopenharmony_ci *
2863d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
2864d5ac70f0Sopenharmony_ci */
2865d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
2866d5ac70f0Sopenharmony_ci{
2867d5ac70f0Sopenharmony_ci	assert(info);
2868d5ac70f0Sopenharmony_ci	info->queue = q;
2869d5ac70f0Sopenharmony_ci}
2870d5ac70f0Sopenharmony_ci
2871d5ac70f0Sopenharmony_ci/**
2872d5ac70f0Sopenharmony_ci * \brief Set the exclusive mode of a port_subscribe container
2873d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2874d5ac70f0Sopenharmony_ci * \param val non-zero to enable
2875d5ac70f0Sopenharmony_ci *
2876d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
2877d5ac70f0Sopenharmony_ci */
2878d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
2879d5ac70f0Sopenharmony_ci{
2880d5ac70f0Sopenharmony_ci	assert(info);
2881d5ac70f0Sopenharmony_ci	if (val)
2882d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2883d5ac70f0Sopenharmony_ci	else
2884d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2885d5ac70f0Sopenharmony_ci}
2886d5ac70f0Sopenharmony_ci
2887d5ac70f0Sopenharmony_ci/**
2888d5ac70f0Sopenharmony_ci * \brief Set the time-update mode of a port_subscribe container
2889d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2890d5ac70f0Sopenharmony_ci * \param val non-zero to enable
2891d5ac70f0Sopenharmony_ci *
2892d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
2893d5ac70f0Sopenharmony_ci */
2894d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
2895d5ac70f0Sopenharmony_ci{
2896d5ac70f0Sopenharmony_ci	assert(info);
2897d5ac70f0Sopenharmony_ci	if (val)
2898d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2899d5ac70f0Sopenharmony_ci	else
2900d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2901d5ac70f0Sopenharmony_ci}
2902d5ac70f0Sopenharmony_ci
2903d5ac70f0Sopenharmony_ci/**
2904d5ac70f0Sopenharmony_ci * \brief Set the real-time mode of a port_subscribe container
2905d5ac70f0Sopenharmony_ci * \param info port_subscribe container
2906d5ac70f0Sopenharmony_ci * \param val non-zero to enable
2907d5ac70f0Sopenharmony_ci *
2908d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
2909d5ac70f0Sopenharmony_ci */
2910d5ac70f0Sopenharmony_civoid snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
2911d5ac70f0Sopenharmony_ci{
2912d5ac70f0Sopenharmony_ci	assert(info);
2913d5ac70f0Sopenharmony_ci	if (val)
2914d5ac70f0Sopenharmony_ci		info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2915d5ac70f0Sopenharmony_ci	else
2916d5ac70f0Sopenharmony_ci		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2917d5ac70f0Sopenharmony_ci}
2918d5ac70f0Sopenharmony_ci
2919d5ac70f0Sopenharmony_ci
2920d5ac70f0Sopenharmony_ci/**
2921d5ac70f0Sopenharmony_ci * \brief obtain subscription information
2922d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2923d5ac70f0Sopenharmony_ci * \param sub pointer to return the subscription information
2924d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2925d5ac70f0Sopenharmony_ci *
2926d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
2927d5ac70f0Sopenharmony_ci */
2928d5ac70f0Sopenharmony_ciint snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2929d5ac70f0Sopenharmony_ci{
2930d5ac70f0Sopenharmony_ci	assert(seq && sub);
2931d5ac70f0Sopenharmony_ci	return seq->ops->get_port_subscription(seq, sub);
2932d5ac70f0Sopenharmony_ci}
2933d5ac70f0Sopenharmony_ci
2934d5ac70f0Sopenharmony_ci/**
2935d5ac70f0Sopenharmony_ci * \brief subscribe a port connection
2936d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2937d5ac70f0Sopenharmony_ci * \param sub subscription information
2938d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2939d5ac70f0Sopenharmony_ci *
2940d5ac70f0Sopenharmony_ci * Subscribes a connection between two ports.
2941d5ac70f0Sopenharmony_ci * The subscription information is stored in sub argument.
2942d5ac70f0Sopenharmony_ci *
2943d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
2944d5ac70f0Sopenharmony_ci *     snd_seq_connect_from(), snd_seq_connect_to()
2945d5ac70f0Sopenharmony_ci */
2946d5ac70f0Sopenharmony_ciint snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2947d5ac70f0Sopenharmony_ci{
2948d5ac70f0Sopenharmony_ci	assert(seq && sub);
2949d5ac70f0Sopenharmony_ci	return seq->ops->subscribe_port(seq, sub);
2950d5ac70f0Sopenharmony_ci}
2951d5ac70f0Sopenharmony_ci
2952d5ac70f0Sopenharmony_ci/**
2953d5ac70f0Sopenharmony_ci * \brief unsubscribe a connection between ports
2954d5ac70f0Sopenharmony_ci * \param seq sequencer handle
2955d5ac70f0Sopenharmony_ci * \param sub subscription information to disconnect
2956d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
2957d5ac70f0Sopenharmony_ci *
2958d5ac70f0Sopenharmony_ci * Unsubscribes a connection between two ports,
2959d5ac70f0Sopenharmony_ci * described in sender and dest fields in sub argument.
2960d5ac70f0Sopenharmony_ci *
2961d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
2962d5ac70f0Sopenharmony_ci */
2963d5ac70f0Sopenharmony_ciint snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2964d5ac70f0Sopenharmony_ci{
2965d5ac70f0Sopenharmony_ci	assert(seq && sub);
2966d5ac70f0Sopenharmony_ci	return seq->ops->unsubscribe_port(seq, sub);
2967d5ac70f0Sopenharmony_ci}
2968d5ac70f0Sopenharmony_ci
2969d5ac70f0Sopenharmony_ci
2970d5ac70f0Sopenharmony_ci/**
2971d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_query_subscribe_t
2972d5ac70f0Sopenharmony_ci * \return size in bytes
2973d5ac70f0Sopenharmony_ci */
2974d5ac70f0Sopenharmony_cisize_t snd_seq_query_subscribe_sizeof()
2975d5ac70f0Sopenharmony_ci{
2976d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_query_subscribe_t);
2977d5ac70f0Sopenharmony_ci}
2978d5ac70f0Sopenharmony_ci
2979d5ac70f0Sopenharmony_ci/**
2980d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
2981d5ac70f0Sopenharmony_ci * \param ptr returned pointer
2982d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
2983d5ac70f0Sopenharmony_ci */
2984d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
2985d5ac70f0Sopenharmony_ci{
2986d5ac70f0Sopenharmony_ci	assert(ptr);
2987d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
2988d5ac70f0Sopenharmony_ci	if (!*ptr)
2989d5ac70f0Sopenharmony_ci		return -ENOMEM;
2990d5ac70f0Sopenharmony_ci	return 0;
2991d5ac70f0Sopenharmony_ci}
2992d5ac70f0Sopenharmony_ci
2993d5ac70f0Sopenharmony_ci/**
2994d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_query_subscribe_t
2995d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
2996d5ac70f0Sopenharmony_ci */
2997d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
2998d5ac70f0Sopenharmony_ci{
2999d5ac70f0Sopenharmony_ci	free(obj);
3000d5ac70f0Sopenharmony_ci}
3001d5ac70f0Sopenharmony_ci
3002d5ac70f0Sopenharmony_ci/**
3003d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_query_subscribe_t to another
3004d5ac70f0Sopenharmony_ci * \param dst pointer to destination
3005d5ac70f0Sopenharmony_ci * \param src pointer to source
3006d5ac70f0Sopenharmony_ci */
3007d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
3008d5ac70f0Sopenharmony_ci{
3009d5ac70f0Sopenharmony_ci	assert(dst && src);
3010d5ac70f0Sopenharmony_ci	*dst = *src;
3011d5ac70f0Sopenharmony_ci}
3012d5ac70f0Sopenharmony_ci
3013d5ac70f0Sopenharmony_ci
3014d5ac70f0Sopenharmony_ci/**
3015d5ac70f0Sopenharmony_ci * \brief Get the client id of a query_subscribe container
3016d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3017d5ac70f0Sopenharmony_ci * \return client id
3018d5ac70f0Sopenharmony_ci *
3019d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
3020d5ac70f0Sopenharmony_ci */
3021d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
3022d5ac70f0Sopenharmony_ci{
3023d5ac70f0Sopenharmony_ci	assert(info);
3024d5ac70f0Sopenharmony_ci	return info->root.client;
3025d5ac70f0Sopenharmony_ci}
3026d5ac70f0Sopenharmony_ci
3027d5ac70f0Sopenharmony_ci/**
3028d5ac70f0Sopenharmony_ci * \brief Get the port id of a query_subscribe container
3029d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3030d5ac70f0Sopenharmony_ci * \return port id
3031d5ac70f0Sopenharmony_ci *
3032d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
3033d5ac70f0Sopenharmony_ci */
3034d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
3035d5ac70f0Sopenharmony_ci{
3036d5ac70f0Sopenharmony_ci	assert(info);
3037d5ac70f0Sopenharmony_ci	return info->root.port;
3038d5ac70f0Sopenharmony_ci}
3039d5ac70f0Sopenharmony_ci
3040d5ac70f0Sopenharmony_ci/**
3041d5ac70f0Sopenharmony_ci * \brief Get the client/port address of a query_subscribe container
3042d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3043d5ac70f0Sopenharmony_ci * \return client/port address pointer
3044d5ac70f0Sopenharmony_ci *
3045d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
3046d5ac70f0Sopenharmony_ci */
3047d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
3048d5ac70f0Sopenharmony_ci{
3049d5ac70f0Sopenharmony_ci	assert(info);
3050d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *)&info->root;
3051d5ac70f0Sopenharmony_ci}
3052d5ac70f0Sopenharmony_ci
3053d5ac70f0Sopenharmony_ci/**
3054d5ac70f0Sopenharmony_ci * \brief Get the query type of a query_subscribe container
3055d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3056d5ac70f0Sopenharmony_ci * \return query type
3057d5ac70f0Sopenharmony_ci *
3058d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
3059d5ac70f0Sopenharmony_ci */
3060d5ac70f0Sopenharmony_cisnd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
3061d5ac70f0Sopenharmony_ci{
3062d5ac70f0Sopenharmony_ci	assert(info);
3063d5ac70f0Sopenharmony_ci	return info->type;
3064d5ac70f0Sopenharmony_ci}
3065d5ac70f0Sopenharmony_ci
3066d5ac70f0Sopenharmony_ci/**
3067d5ac70f0Sopenharmony_ci * \brief Get the index of subscriber of a query_subscribe container
3068d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3069d5ac70f0Sopenharmony_ci * \return subscriber's index
3070d5ac70f0Sopenharmony_ci *
3071d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
3072d5ac70f0Sopenharmony_ci */
3073d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
3074d5ac70f0Sopenharmony_ci{
3075d5ac70f0Sopenharmony_ci	assert(info);
3076d5ac70f0Sopenharmony_ci	return info->index;
3077d5ac70f0Sopenharmony_ci}
3078d5ac70f0Sopenharmony_ci
3079d5ac70f0Sopenharmony_ci/**
3080d5ac70f0Sopenharmony_ci * \brief Get the number of subscriptions of a query_subscribe container
3081d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3082d5ac70f0Sopenharmony_ci * \return number of subscriptions
3083d5ac70f0Sopenharmony_ci *
3084d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3085d5ac70f0Sopenharmony_ci */
3086d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
3087d5ac70f0Sopenharmony_ci{
3088d5ac70f0Sopenharmony_ci	assert(info);
3089d5ac70f0Sopenharmony_ci	return info->num_subs;
3090d5ac70f0Sopenharmony_ci}
3091d5ac70f0Sopenharmony_ci
3092d5ac70f0Sopenharmony_ci/**
3093d5ac70f0Sopenharmony_ci * \brief Get the address of subscriber of a query_subscribe container
3094d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3095d5ac70f0Sopenharmony_ci * \return subscriber's address pointer
3096d5ac70f0Sopenharmony_ci *
3097d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3098d5ac70f0Sopenharmony_ci */
3099d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
3100d5ac70f0Sopenharmony_ci{
3101d5ac70f0Sopenharmony_ci	assert(info);
3102d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *)&info->addr;
3103d5ac70f0Sopenharmony_ci}
3104d5ac70f0Sopenharmony_ci
3105d5ac70f0Sopenharmony_ci/**
3106d5ac70f0Sopenharmony_ci * \brief Get the queue id of subscriber of a query_subscribe container
3107d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3108d5ac70f0Sopenharmony_ci * \return subscriber's queue id
3109d5ac70f0Sopenharmony_ci *
3110d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3111d5ac70f0Sopenharmony_ci */
3112d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
3113d5ac70f0Sopenharmony_ci{
3114d5ac70f0Sopenharmony_ci	assert(info);
3115d5ac70f0Sopenharmony_ci	return info->queue;
3116d5ac70f0Sopenharmony_ci}
3117d5ac70f0Sopenharmony_ci
3118d5ac70f0Sopenharmony_ci/**
3119d5ac70f0Sopenharmony_ci * \brief Get the exclusive mode of a query_subscribe container
3120d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3121d5ac70f0Sopenharmony_ci * \return 1 if exclusive mode
3122d5ac70f0Sopenharmony_ci *
3123d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3124d5ac70f0Sopenharmony_ci */
3125d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
3126d5ac70f0Sopenharmony_ci{
3127d5ac70f0Sopenharmony_ci	assert(info);
3128d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
3129d5ac70f0Sopenharmony_ci}
3130d5ac70f0Sopenharmony_ci
3131d5ac70f0Sopenharmony_ci/**
3132d5ac70f0Sopenharmony_ci * \brief Get the time-update mode of a query_subscribe container
3133d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3134d5ac70f0Sopenharmony_ci * \return 1 if update timestamp
3135d5ac70f0Sopenharmony_ci *
3136d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3137d5ac70f0Sopenharmony_ci */
3138d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
3139d5ac70f0Sopenharmony_ci{
3140d5ac70f0Sopenharmony_ci	assert(info);
3141d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
3142d5ac70f0Sopenharmony_ci}
3143d5ac70f0Sopenharmony_ci
3144d5ac70f0Sopenharmony_ci/**
3145d5ac70f0Sopenharmony_ci * \brief Get the real-time update mode of a query_subscribe container
3146d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3147d5ac70f0Sopenharmony_ci * \return 1 if real-time update mode
3148d5ac70f0Sopenharmony_ci *
3149d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers()
3150d5ac70f0Sopenharmony_ci */
3151d5ac70f0Sopenharmony_ciint snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
3152d5ac70f0Sopenharmony_ci{
3153d5ac70f0Sopenharmony_ci	assert(info);
3154d5ac70f0Sopenharmony_ci	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
3155d5ac70f0Sopenharmony_ci}
3156d5ac70f0Sopenharmony_ci
3157d5ac70f0Sopenharmony_ci/**
3158d5ac70f0Sopenharmony_ci * \brief Set the client id of a query_subscribe container
3159d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3160d5ac70f0Sopenharmony_ci * \param client client id
3161d5ac70f0Sopenharmony_ci *
3162d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
3163d5ac70f0Sopenharmony_ci */
3164d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
3165d5ac70f0Sopenharmony_ci{
3166d5ac70f0Sopenharmony_ci	assert(info);
3167d5ac70f0Sopenharmony_ci	info->root.client = client;
3168d5ac70f0Sopenharmony_ci}
3169d5ac70f0Sopenharmony_ci
3170d5ac70f0Sopenharmony_ci/**
3171d5ac70f0Sopenharmony_ci * \brief Set the port id of a query_subscribe container
3172d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3173d5ac70f0Sopenharmony_ci * \param port port id
3174d5ac70f0Sopenharmony_ci *
3175d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
3176d5ac70f0Sopenharmony_ci */
3177d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
3178d5ac70f0Sopenharmony_ci{
3179d5ac70f0Sopenharmony_ci	assert(info);
3180d5ac70f0Sopenharmony_ci	info->root.port = port;
3181d5ac70f0Sopenharmony_ci}
3182d5ac70f0Sopenharmony_ci
3183d5ac70f0Sopenharmony_ci/**
3184d5ac70f0Sopenharmony_ci * \brief Set the client/port address of a query_subscribe container
3185d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3186d5ac70f0Sopenharmony_ci * \param addr client/port address pointer
3187d5ac70f0Sopenharmony_ci *
3188d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
3189d5ac70f0Sopenharmony_ci */
3190d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
3191d5ac70f0Sopenharmony_ci{
3192d5ac70f0Sopenharmony_ci	assert(info);
3193d5ac70f0Sopenharmony_ci	info->root = *(const struct snd_seq_addr *)addr;
3194d5ac70f0Sopenharmony_ci}
3195d5ac70f0Sopenharmony_ci
3196d5ac70f0Sopenharmony_ci/**
3197d5ac70f0Sopenharmony_ci * \brief Set the query type of a query_subscribe container
3198d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3199d5ac70f0Sopenharmony_ci * \param type query type
3200d5ac70f0Sopenharmony_ci *
3201d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
3202d5ac70f0Sopenharmony_ci */
3203d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
3204d5ac70f0Sopenharmony_ci{
3205d5ac70f0Sopenharmony_ci	assert(info);
3206d5ac70f0Sopenharmony_ci	info->type = type;
3207d5ac70f0Sopenharmony_ci}
3208d5ac70f0Sopenharmony_ci
3209d5ac70f0Sopenharmony_ci/**
3210d5ac70f0Sopenharmony_ci * \brief Set the subscriber's index to be queried
3211d5ac70f0Sopenharmony_ci * \param info query_subscribe container
3212d5ac70f0Sopenharmony_ci * \param index index to be queried
3213d5ac70f0Sopenharmony_ci *
3214d5ac70f0Sopenharmony_ci * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
3215d5ac70f0Sopenharmony_ci */
3216d5ac70f0Sopenharmony_civoid snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
3217d5ac70f0Sopenharmony_ci{
3218d5ac70f0Sopenharmony_ci	assert(info);
3219d5ac70f0Sopenharmony_ci	info->index = index;
3220d5ac70f0Sopenharmony_ci}
3221d5ac70f0Sopenharmony_ci
3222d5ac70f0Sopenharmony_ci
3223d5ac70f0Sopenharmony_ci/**
3224d5ac70f0Sopenharmony_ci * \brief query port subscriber list
3225d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3226d5ac70f0Sopenharmony_ci * \param subs subscription to query
3227d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3228d5ac70f0Sopenharmony_ci *
3229d5ac70f0Sopenharmony_ci * Queries the subscribers accessing to a port.
3230d5ac70f0Sopenharmony_ci * The query information is specified in subs argument.
3231d5ac70f0Sopenharmony_ci *
3232d5ac70f0Sopenharmony_ci * At least, the client id, the port id, the index number and
3233d5ac70f0Sopenharmony_ci * the query type must be set to perform a proper query.
3234d5ac70f0Sopenharmony_ci * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
3235d5ac70f0Sopenharmony_ci * can be specified to check whether the readers or the writers to the port.
3236d5ac70f0Sopenharmony_ci * To query the first subscription, set 0 to the index number.  To list up
3237d5ac70f0Sopenharmony_ci * all the subscriptions, call this function with the index numbers from 0
3238d5ac70f0Sopenharmony_ci * until this returns a negative value.
3239d5ac70f0Sopenharmony_ci *
3240d5ac70f0Sopenharmony_ci * \sa snd_seq_get_port_subscription()
3241d5ac70f0Sopenharmony_ci */
3242d5ac70f0Sopenharmony_ciint snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
3243d5ac70f0Sopenharmony_ci{
3244d5ac70f0Sopenharmony_ci	assert(seq && subs);
3245d5ac70f0Sopenharmony_ci	return seq->ops->query_port_subscribers(seq, subs);
3246d5ac70f0Sopenharmony_ci}
3247d5ac70f0Sopenharmony_ci
3248d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
3249d5ac70f0Sopenharmony_ci
3250d5ac70f0Sopenharmony_ci/*
3251d5ac70f0Sopenharmony_ci * queue handlers
3252d5ac70f0Sopenharmony_ci */
3253d5ac70f0Sopenharmony_ci
3254d5ac70f0Sopenharmony_ci/**
3255d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_queue_info_t
3256d5ac70f0Sopenharmony_ci * \return size in bytes
3257d5ac70f0Sopenharmony_ci */
3258d5ac70f0Sopenharmony_cisize_t snd_seq_queue_info_sizeof()
3259d5ac70f0Sopenharmony_ci{
3260d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_queue_info_t);
3261d5ac70f0Sopenharmony_ci}
3262d5ac70f0Sopenharmony_ci
3263d5ac70f0Sopenharmony_ci/**
3264d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
3265d5ac70f0Sopenharmony_ci * \param ptr returned pointer
3266d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
3267d5ac70f0Sopenharmony_ci */
3268d5ac70f0Sopenharmony_ciint snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
3269d5ac70f0Sopenharmony_ci{
3270d5ac70f0Sopenharmony_ci	assert(ptr);
3271d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_queue_info_t));
3272d5ac70f0Sopenharmony_ci	if (!*ptr)
3273d5ac70f0Sopenharmony_ci		return -ENOMEM;
3274d5ac70f0Sopenharmony_ci	return 0;
3275d5ac70f0Sopenharmony_ci}
3276d5ac70f0Sopenharmony_ci
3277d5ac70f0Sopenharmony_ci/**
3278d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_queue_info_t
3279d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
3280d5ac70f0Sopenharmony_ci */
3281d5ac70f0Sopenharmony_civoid snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
3282d5ac70f0Sopenharmony_ci{
3283d5ac70f0Sopenharmony_ci	free(obj);
3284d5ac70f0Sopenharmony_ci}
3285d5ac70f0Sopenharmony_ci
3286d5ac70f0Sopenharmony_ci/**
3287d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_queue_info_t to another
3288d5ac70f0Sopenharmony_ci * \param dst pointer to destination
3289d5ac70f0Sopenharmony_ci * \param src pointer to source
3290d5ac70f0Sopenharmony_ci */
3291d5ac70f0Sopenharmony_civoid snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
3292d5ac70f0Sopenharmony_ci{
3293d5ac70f0Sopenharmony_ci	assert(dst && src);
3294d5ac70f0Sopenharmony_ci	*dst = *src;
3295d5ac70f0Sopenharmony_ci}
3296d5ac70f0Sopenharmony_ci
3297d5ac70f0Sopenharmony_ci
3298d5ac70f0Sopenharmony_ci/**
3299d5ac70f0Sopenharmony_ci * \brief Get the queue id of a queue_info container
3300d5ac70f0Sopenharmony_ci * \param info queue_info container
3301d5ac70f0Sopenharmony_ci * \return queue id
3302d5ac70f0Sopenharmony_ci *
3303d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
3304d5ac70f0Sopenharmony_ci */
3305d5ac70f0Sopenharmony_ciint snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
3306d5ac70f0Sopenharmony_ci{
3307d5ac70f0Sopenharmony_ci	assert(info);
3308d5ac70f0Sopenharmony_ci	return info->queue;
3309d5ac70f0Sopenharmony_ci}
3310d5ac70f0Sopenharmony_ci
3311d5ac70f0Sopenharmony_ci/**
3312d5ac70f0Sopenharmony_ci * \brief Get the name of a queue_info container
3313d5ac70f0Sopenharmony_ci * \param info queue_info container
3314d5ac70f0Sopenharmony_ci * \return name string
3315d5ac70f0Sopenharmony_ci *
3316d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
3317d5ac70f0Sopenharmony_ci */
3318d5ac70f0Sopenharmony_ciconst char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
3319d5ac70f0Sopenharmony_ci{
3320d5ac70f0Sopenharmony_ci	assert(info);
3321d5ac70f0Sopenharmony_ci	return info->name;
3322d5ac70f0Sopenharmony_ci}
3323d5ac70f0Sopenharmony_ci
3324d5ac70f0Sopenharmony_ci/**
3325d5ac70f0Sopenharmony_ci * \brief Get the owner client id of a queue_info container
3326d5ac70f0Sopenharmony_ci * \param info queue_info container
3327d5ac70f0Sopenharmony_ci * \return owner client id
3328d5ac70f0Sopenharmony_ci *
3329d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
3330d5ac70f0Sopenharmony_ci */
3331d5ac70f0Sopenharmony_ciint snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
3332d5ac70f0Sopenharmony_ci{
3333d5ac70f0Sopenharmony_ci	assert(info);
3334d5ac70f0Sopenharmony_ci	return info->owner;
3335d5ac70f0Sopenharmony_ci}
3336d5ac70f0Sopenharmony_ci
3337d5ac70f0Sopenharmony_ci/**
3338d5ac70f0Sopenharmony_ci * \brief Get the lock status of a queue_info container
3339d5ac70f0Sopenharmony_ci * \param info queue_info container
3340d5ac70f0Sopenharmony_ci * \return lock status --- non-zero = locked
3341d5ac70f0Sopenharmony_ci *
3342d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
3343d5ac70f0Sopenharmony_ci */
3344d5ac70f0Sopenharmony_ciint snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
3345d5ac70f0Sopenharmony_ci{
3346d5ac70f0Sopenharmony_ci	assert(info);
3347d5ac70f0Sopenharmony_ci	return info->locked;
3348d5ac70f0Sopenharmony_ci}
3349d5ac70f0Sopenharmony_ci
3350d5ac70f0Sopenharmony_ci/**
3351d5ac70f0Sopenharmony_ci * \brief Get the conditional bit flags of a queue_info container
3352d5ac70f0Sopenharmony_ci * \param info queue_info container
3353d5ac70f0Sopenharmony_ci * \return conditional bit flags
3354d5ac70f0Sopenharmony_ci *
3355d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
3356d5ac70f0Sopenharmony_ci */
3357d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
3358d5ac70f0Sopenharmony_ci{
3359d5ac70f0Sopenharmony_ci	assert(info);
3360d5ac70f0Sopenharmony_ci	return info->flags;
3361d5ac70f0Sopenharmony_ci}
3362d5ac70f0Sopenharmony_ci
3363d5ac70f0Sopenharmony_ci/**
3364d5ac70f0Sopenharmony_ci * \brief Set the name of a queue_info container
3365d5ac70f0Sopenharmony_ci * \param info queue_info container
3366d5ac70f0Sopenharmony_ci * \param name name string
3367d5ac70f0Sopenharmony_ci *
3368d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
3369d5ac70f0Sopenharmony_ci */
3370d5ac70f0Sopenharmony_civoid snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
3371d5ac70f0Sopenharmony_ci{
3372d5ac70f0Sopenharmony_ci	assert(info && name);
3373d5ac70f0Sopenharmony_ci	snd_strlcpy(info->name, name, sizeof(info->name));
3374d5ac70f0Sopenharmony_ci}
3375d5ac70f0Sopenharmony_ci
3376d5ac70f0Sopenharmony_ci/**
3377d5ac70f0Sopenharmony_ci * \brief Set the owner client id of a queue_info container
3378d5ac70f0Sopenharmony_ci * \param info queue_info container
3379d5ac70f0Sopenharmony_ci * \param owner client id
3380d5ac70f0Sopenharmony_ci *
3381d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
3382d5ac70f0Sopenharmony_ci */
3383d5ac70f0Sopenharmony_civoid snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
3384d5ac70f0Sopenharmony_ci{
3385d5ac70f0Sopenharmony_ci	assert(info);
3386d5ac70f0Sopenharmony_ci	info->owner = owner;
3387d5ac70f0Sopenharmony_ci}
3388d5ac70f0Sopenharmony_ci
3389d5ac70f0Sopenharmony_ci/**
3390d5ac70f0Sopenharmony_ci * \brief Set the lock status of a queue_info container
3391d5ac70f0Sopenharmony_ci * \param info queue_info container
3392d5ac70f0Sopenharmony_ci * \param locked lock status
3393d5ac70f0Sopenharmony_ci *
3394d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
3395d5ac70f0Sopenharmony_ci */
3396d5ac70f0Sopenharmony_civoid snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
3397d5ac70f0Sopenharmony_ci{
3398d5ac70f0Sopenharmony_ci	assert(info);
3399d5ac70f0Sopenharmony_ci	info->locked = locked;
3400d5ac70f0Sopenharmony_ci}
3401d5ac70f0Sopenharmony_ci
3402d5ac70f0Sopenharmony_ci/**
3403d5ac70f0Sopenharmony_ci * \brief Set the conditional bit flags of a queue_info container
3404d5ac70f0Sopenharmony_ci * \param info queue_info container
3405d5ac70f0Sopenharmony_ci * \param flags conditional bit flags
3406d5ac70f0Sopenharmony_ci *
3407d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
3408d5ac70f0Sopenharmony_ci */
3409d5ac70f0Sopenharmony_civoid snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
3410d5ac70f0Sopenharmony_ci{
3411d5ac70f0Sopenharmony_ci	assert(info);
3412d5ac70f0Sopenharmony_ci	info->flags = flags;
3413d5ac70f0Sopenharmony_ci}
3414d5ac70f0Sopenharmony_ci
3415d5ac70f0Sopenharmony_ci
3416d5ac70f0Sopenharmony_ci/**
3417d5ac70f0Sopenharmony_ci * \brief create a queue
3418d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3419d5ac70f0Sopenharmony_ci * \param info queue information to initialize
3420d5ac70f0Sopenharmony_ci * \return the queue id (zero or positive) on success otherwise a negative error code
3421d5ac70f0Sopenharmony_ci *
3422d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_queue()
3423d5ac70f0Sopenharmony_ci */
3424d5ac70f0Sopenharmony_ciint snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
3425d5ac70f0Sopenharmony_ci{
3426d5ac70f0Sopenharmony_ci	int err;
3427d5ac70f0Sopenharmony_ci	assert(seq && info);
3428d5ac70f0Sopenharmony_ci	info->owner = seq->client;
3429d5ac70f0Sopenharmony_ci	err = seq->ops->create_queue(seq, info);
3430d5ac70f0Sopenharmony_ci	if (err < 0)
3431d5ac70f0Sopenharmony_ci		return err;
3432d5ac70f0Sopenharmony_ci	return info->queue;
3433d5ac70f0Sopenharmony_ci}
3434d5ac70f0Sopenharmony_ci
3435d5ac70f0Sopenharmony_ci/**
3436d5ac70f0Sopenharmony_ci * \brief allocate a queue with the specified name
3437d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3438d5ac70f0Sopenharmony_ci * \param name the name of the new queue
3439d5ac70f0Sopenharmony_ci * \return the queue id (zero or positive) on success otherwise a negative error code
3440d5ac70f0Sopenharmony_ci *
3441d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_queue()
3442d5ac70f0Sopenharmony_ci */
3443d5ac70f0Sopenharmony_ciint snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
3444d5ac70f0Sopenharmony_ci{
3445d5ac70f0Sopenharmony_ci	snd_seq_queue_info_t info;
3446d5ac70f0Sopenharmony_ci	memset(&info, 0, sizeof(info));
3447d5ac70f0Sopenharmony_ci	info.locked = 1;
3448d5ac70f0Sopenharmony_ci	if (name)
3449d5ac70f0Sopenharmony_ci		snd_strlcpy(info.name, name, sizeof(info.name));
3450d5ac70f0Sopenharmony_ci	return snd_seq_create_queue(seq, &info);
3451d5ac70f0Sopenharmony_ci}
3452d5ac70f0Sopenharmony_ci
3453d5ac70f0Sopenharmony_ci/**
3454d5ac70f0Sopenharmony_ci * \brief allocate a queue
3455d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3456d5ac70f0Sopenharmony_ci * \return the queue id (zero or positive) on success otherwise a negative error code
3457d5ac70f0Sopenharmony_ci *
3458d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
3459d5ac70f0Sopenharmony_ci *     snd_seq_get_queue_info()
3460d5ac70f0Sopenharmony_ci */
3461d5ac70f0Sopenharmony_ciint snd_seq_alloc_queue(snd_seq_t *seq)
3462d5ac70f0Sopenharmony_ci{
3463d5ac70f0Sopenharmony_ci	return snd_seq_alloc_named_queue(seq, NULL);
3464d5ac70f0Sopenharmony_ci}
3465d5ac70f0Sopenharmony_ci
3466d5ac70f0Sopenharmony_ci/**
3467d5ac70f0Sopenharmony_ci * \brief delete the specified queue
3468d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3469d5ac70f0Sopenharmony_ci * \param q queue id to delete
3470d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3471d5ac70f0Sopenharmony_ci *
3472d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_queue()
3473d5ac70f0Sopenharmony_ci */
3474d5ac70f0Sopenharmony_ciint snd_seq_free_queue(snd_seq_t *seq, int q)
3475d5ac70f0Sopenharmony_ci{
3476d5ac70f0Sopenharmony_ci	snd_seq_queue_info_t info;
3477d5ac70f0Sopenharmony_ci	assert(seq);
3478d5ac70f0Sopenharmony_ci	memset(&info, 0, sizeof(info));
3479d5ac70f0Sopenharmony_ci	info.queue = q;
3480d5ac70f0Sopenharmony_ci	return seq->ops->delete_queue(seq, &info);
3481d5ac70f0Sopenharmony_ci}
3482d5ac70f0Sopenharmony_ci
3483d5ac70f0Sopenharmony_ci/**
3484d5ac70f0Sopenharmony_ci * \brief obtain queue attributes
3485d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3486d5ac70f0Sopenharmony_ci * \param q queue id to query
3487d5ac70f0Sopenharmony_ci * \param info information returned
3488d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3489d5ac70f0Sopenharmony_ci *
3490d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
3491d5ac70f0Sopenharmony_ci */
3492d5ac70f0Sopenharmony_ciint snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3493d5ac70f0Sopenharmony_ci{
3494d5ac70f0Sopenharmony_ci	assert(seq && info);
3495d5ac70f0Sopenharmony_ci	info->queue = q;
3496d5ac70f0Sopenharmony_ci	return seq->ops->get_queue_info(seq, info);
3497d5ac70f0Sopenharmony_ci}
3498d5ac70f0Sopenharmony_ci
3499d5ac70f0Sopenharmony_ci/**
3500d5ac70f0Sopenharmony_ci * \brief change the queue attributes
3501d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3502d5ac70f0Sopenharmony_ci * \param q queue id to change
3503d5ac70f0Sopenharmony_ci * \param info information changed
3504d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3505d5ac70f0Sopenharmony_ci *
3506d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info()
3507d5ac70f0Sopenharmony_ci */
3508d5ac70f0Sopenharmony_ciint snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3509d5ac70f0Sopenharmony_ci{
3510d5ac70f0Sopenharmony_ci	assert(seq && info);
3511d5ac70f0Sopenharmony_ci	info->queue = q;
3512d5ac70f0Sopenharmony_ci	return seq->ops->set_queue_info(seq, info);
3513d5ac70f0Sopenharmony_ci}
3514d5ac70f0Sopenharmony_ci
3515d5ac70f0Sopenharmony_ci/**
3516d5ac70f0Sopenharmony_ci * \brief query the matching queue with the specified name
3517d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3518d5ac70f0Sopenharmony_ci * \param name the name string to query
3519d5ac70f0Sopenharmony_ci * \return the queue id if found or negative error code
3520d5ac70f0Sopenharmony_ci *
3521d5ac70f0Sopenharmony_ci * Searches the matching queue with the specified name string.
3522d5ac70f0Sopenharmony_ci *
3523d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info()
3524d5ac70f0Sopenharmony_ci */
3525d5ac70f0Sopenharmony_ciint snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
3526d5ac70f0Sopenharmony_ci{
3527d5ac70f0Sopenharmony_ci	int err;
3528d5ac70f0Sopenharmony_ci	snd_seq_queue_info_t info;
3529d5ac70f0Sopenharmony_ci	assert(seq && name);
3530d5ac70f0Sopenharmony_ci	snd_strlcpy(info.name, name, sizeof(info.name));
3531d5ac70f0Sopenharmony_ci	err = seq->ops->get_named_queue(seq, &info);
3532d5ac70f0Sopenharmony_ci	if (err < 0)
3533d5ac70f0Sopenharmony_ci		return err;
3534d5ac70f0Sopenharmony_ci	return info.queue;
3535d5ac70f0Sopenharmony_ci}
3536d5ac70f0Sopenharmony_ci
3537d5ac70f0Sopenharmony_ci/**
3538d5ac70f0Sopenharmony_ci * \brief Get the queue usage flag to the client
3539d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3540d5ac70f0Sopenharmony_ci * \param q queue id
3541d5ac70f0Sopenharmony_ci * \return 1 = client is allowed to access the queue, 0 = not allowed,
3542d5ac70f0Sopenharmony_ci *     otherwise a negative error code
3543d5ac70f0Sopenharmony_ci *
3544d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3545d5ac70f0Sopenharmony_ci */
3546d5ac70f0Sopenharmony_ciint snd_seq_get_queue_usage(snd_seq_t *seq, int q)
3547d5ac70f0Sopenharmony_ci{
3548d5ac70f0Sopenharmony_ci	struct snd_seq_queue_client info;
3549d5ac70f0Sopenharmony_ci	int err;
3550d5ac70f0Sopenharmony_ci	assert(seq);
3551d5ac70f0Sopenharmony_ci	memset(&info, 0, sizeof(info));
3552d5ac70f0Sopenharmony_ci	info.queue = q;
3553d5ac70f0Sopenharmony_ci	info.client = seq->client;
3554d5ac70f0Sopenharmony_ci	if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
3555d5ac70f0Sopenharmony_ci		return err;
3556d5ac70f0Sopenharmony_ci	return info.used;
3557d5ac70f0Sopenharmony_ci}
3558d5ac70f0Sopenharmony_ci
3559d5ac70f0Sopenharmony_ci/**
3560d5ac70f0Sopenharmony_ci * \brief Set the queue usage flag to the client
3561d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3562d5ac70f0Sopenharmony_ci * \param q queue id
3563d5ac70f0Sopenharmony_ci * \param used non-zero if the client is allowed
3564d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3565d5ac70f0Sopenharmony_ci *
3566d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3567d5ac70f0Sopenharmony_ci */
3568d5ac70f0Sopenharmony_ciint snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
3569d5ac70f0Sopenharmony_ci{
3570d5ac70f0Sopenharmony_ci	struct snd_seq_queue_client info;
3571d5ac70f0Sopenharmony_ci	assert(seq);
3572d5ac70f0Sopenharmony_ci	memset(&info, 0, sizeof(info));
3573d5ac70f0Sopenharmony_ci	info.queue = q;
3574d5ac70f0Sopenharmony_ci	info.client = seq->client;
3575d5ac70f0Sopenharmony_ci	info.used = used ? 1 : 0;
3576d5ac70f0Sopenharmony_ci	return seq->ops->set_queue_client(seq, &info);
3577d5ac70f0Sopenharmony_ci}
3578d5ac70f0Sopenharmony_ci
3579d5ac70f0Sopenharmony_ci
3580d5ac70f0Sopenharmony_ci/**
3581d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_queue_status_t
3582d5ac70f0Sopenharmony_ci * \return size in bytes
3583d5ac70f0Sopenharmony_ci */
3584d5ac70f0Sopenharmony_cisize_t snd_seq_queue_status_sizeof()
3585d5ac70f0Sopenharmony_ci{
3586d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_queue_status_t);
3587d5ac70f0Sopenharmony_ci}
3588d5ac70f0Sopenharmony_ci
3589d5ac70f0Sopenharmony_ci/**
3590d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
3591d5ac70f0Sopenharmony_ci * \param ptr returned pointer
3592d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
3593d5ac70f0Sopenharmony_ci */
3594d5ac70f0Sopenharmony_ciint snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
3595d5ac70f0Sopenharmony_ci{
3596d5ac70f0Sopenharmony_ci	assert(ptr);
3597d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_queue_status_t));
3598d5ac70f0Sopenharmony_ci	if (!*ptr)
3599d5ac70f0Sopenharmony_ci		return -ENOMEM;
3600d5ac70f0Sopenharmony_ci	return 0;
3601d5ac70f0Sopenharmony_ci}
3602d5ac70f0Sopenharmony_ci
3603d5ac70f0Sopenharmony_ci/**
3604d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_queue_status_t
3605d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
3606d5ac70f0Sopenharmony_ci */
3607d5ac70f0Sopenharmony_civoid snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
3608d5ac70f0Sopenharmony_ci{
3609d5ac70f0Sopenharmony_ci	free(obj);
3610d5ac70f0Sopenharmony_ci}
3611d5ac70f0Sopenharmony_ci
3612d5ac70f0Sopenharmony_ci/**
3613d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_queue_status_t to another
3614d5ac70f0Sopenharmony_ci * \param dst pointer to destination
3615d5ac70f0Sopenharmony_ci * \param src pointer to source
3616d5ac70f0Sopenharmony_ci */
3617d5ac70f0Sopenharmony_civoid snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
3618d5ac70f0Sopenharmony_ci{
3619d5ac70f0Sopenharmony_ci	assert(dst && src);
3620d5ac70f0Sopenharmony_ci	*dst = *src;
3621d5ac70f0Sopenharmony_ci}
3622d5ac70f0Sopenharmony_ci
3623d5ac70f0Sopenharmony_ci
3624d5ac70f0Sopenharmony_ci/**
3625d5ac70f0Sopenharmony_ci * \brief Get the queue id of a queue_status container
3626d5ac70f0Sopenharmony_ci * \param info queue_status container
3627d5ac70f0Sopenharmony_ci * \return queue id
3628d5ac70f0Sopenharmony_ci *
3629d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_status()
3630d5ac70f0Sopenharmony_ci */
3631d5ac70f0Sopenharmony_ciint snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
3632d5ac70f0Sopenharmony_ci{
3633d5ac70f0Sopenharmony_ci	assert(info);
3634d5ac70f0Sopenharmony_ci	return info->queue;
3635d5ac70f0Sopenharmony_ci}
3636d5ac70f0Sopenharmony_ci
3637d5ac70f0Sopenharmony_ci/**
3638d5ac70f0Sopenharmony_ci * \brief Get the number of events of a queue_status container
3639d5ac70f0Sopenharmony_ci * \param info queue_status container
3640d5ac70f0Sopenharmony_ci * \return number of events
3641d5ac70f0Sopenharmony_ci *
3642d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_status()
3643d5ac70f0Sopenharmony_ci */
3644d5ac70f0Sopenharmony_ciint snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
3645d5ac70f0Sopenharmony_ci{
3646d5ac70f0Sopenharmony_ci	assert(info);
3647d5ac70f0Sopenharmony_ci	return info->events;
3648d5ac70f0Sopenharmony_ci}
3649d5ac70f0Sopenharmony_ci
3650d5ac70f0Sopenharmony_ci/**
3651d5ac70f0Sopenharmony_ci * \brief Get the tick time of a queue_status container
3652d5ac70f0Sopenharmony_ci * \param info queue_status container
3653d5ac70f0Sopenharmony_ci * \return tick time
3654d5ac70f0Sopenharmony_ci *
3655d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_status()
3656d5ac70f0Sopenharmony_ci */
3657d5ac70f0Sopenharmony_cisnd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
3658d5ac70f0Sopenharmony_ci{
3659d5ac70f0Sopenharmony_ci	assert(info);
3660d5ac70f0Sopenharmony_ci	return info->tick;
3661d5ac70f0Sopenharmony_ci}
3662d5ac70f0Sopenharmony_ci
3663d5ac70f0Sopenharmony_ci/**
3664d5ac70f0Sopenharmony_ci * \brief Get the real time of a queue_status container
3665d5ac70f0Sopenharmony_ci * \param info queue_status container
3666d5ac70f0Sopenharmony_ci *
3667d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_status()
3668d5ac70f0Sopenharmony_ci */
3669d5ac70f0Sopenharmony_ciconst snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
3670d5ac70f0Sopenharmony_ci{
3671d5ac70f0Sopenharmony_ci	assert(info);
3672d5ac70f0Sopenharmony_ci	return (const snd_seq_real_time_t *)&info->time;
3673d5ac70f0Sopenharmony_ci}
3674d5ac70f0Sopenharmony_ci
3675d5ac70f0Sopenharmony_ci/**
3676d5ac70f0Sopenharmony_ci * \brief Get the running status bits of a queue_status container
3677d5ac70f0Sopenharmony_ci * \param info queue_status container
3678d5ac70f0Sopenharmony_ci * \return running status bits
3679d5ac70f0Sopenharmony_ci *
3680d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_status()
3681d5ac70f0Sopenharmony_ci */
3682d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
3683d5ac70f0Sopenharmony_ci{
3684d5ac70f0Sopenharmony_ci	assert(info);
3685d5ac70f0Sopenharmony_ci	return info->running;
3686d5ac70f0Sopenharmony_ci}
3687d5ac70f0Sopenharmony_ci
3688d5ac70f0Sopenharmony_ci
3689d5ac70f0Sopenharmony_ci/**
3690d5ac70f0Sopenharmony_ci * \brief obtain the running state of the queue
3691d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3692d5ac70f0Sopenharmony_ci * \param q queue id to query
3693d5ac70f0Sopenharmony_ci * \param status pointer to store the current status
3694d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3695d5ac70f0Sopenharmony_ci *
3696d5ac70f0Sopenharmony_ci * Obtains the running state of the specified queue q.
3697d5ac70f0Sopenharmony_ci */
3698d5ac70f0Sopenharmony_ciint snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
3699d5ac70f0Sopenharmony_ci{
3700d5ac70f0Sopenharmony_ci	assert(seq && status);
3701d5ac70f0Sopenharmony_ci	memset(status, 0, sizeof(snd_seq_queue_status_t));
3702d5ac70f0Sopenharmony_ci	status->queue = q;
3703d5ac70f0Sopenharmony_ci	return seq->ops->get_queue_status(seq, status);
3704d5ac70f0Sopenharmony_ci}
3705d5ac70f0Sopenharmony_ci
3706d5ac70f0Sopenharmony_ci
3707d5ac70f0Sopenharmony_ci/**
3708d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_queue_tempo_t
3709d5ac70f0Sopenharmony_ci * \return size in bytes
3710d5ac70f0Sopenharmony_ci */
3711d5ac70f0Sopenharmony_cisize_t snd_seq_queue_tempo_sizeof()
3712d5ac70f0Sopenharmony_ci{
3713d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_queue_tempo_t);
3714d5ac70f0Sopenharmony_ci}
3715d5ac70f0Sopenharmony_ci
3716d5ac70f0Sopenharmony_ci/**
3717d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
3718d5ac70f0Sopenharmony_ci * \param ptr returned pointer
3719d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
3720d5ac70f0Sopenharmony_ci */
3721d5ac70f0Sopenharmony_ciint snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
3722d5ac70f0Sopenharmony_ci{
3723d5ac70f0Sopenharmony_ci	assert(ptr);
3724d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
3725d5ac70f0Sopenharmony_ci	if (!*ptr)
3726d5ac70f0Sopenharmony_ci		return -ENOMEM;
3727d5ac70f0Sopenharmony_ci	return 0;
3728d5ac70f0Sopenharmony_ci}
3729d5ac70f0Sopenharmony_ci
3730d5ac70f0Sopenharmony_ci/**
3731d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_queue_tempo_t
3732d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
3733d5ac70f0Sopenharmony_ci */
3734d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
3735d5ac70f0Sopenharmony_ci{
3736d5ac70f0Sopenharmony_ci	free(obj);
3737d5ac70f0Sopenharmony_ci}
3738d5ac70f0Sopenharmony_ci
3739d5ac70f0Sopenharmony_ci/**
3740d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_queue_tempo_t to another
3741d5ac70f0Sopenharmony_ci * \param dst pointer to destination
3742d5ac70f0Sopenharmony_ci * \param src pointer to source
3743d5ac70f0Sopenharmony_ci */
3744d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
3745d5ac70f0Sopenharmony_ci{
3746d5ac70f0Sopenharmony_ci	assert(dst && src);
3747d5ac70f0Sopenharmony_ci	*dst = *src;
3748d5ac70f0Sopenharmony_ci}
3749d5ac70f0Sopenharmony_ci
3750d5ac70f0Sopenharmony_ci
3751d5ac70f0Sopenharmony_ci/**
3752d5ac70f0Sopenharmony_ci * \brief Get the queue id of a queue_status container
3753d5ac70f0Sopenharmony_ci * \param info queue_status container
3754d5ac70f0Sopenharmony_ci * \return queue id
3755d5ac70f0Sopenharmony_ci *
3756d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3757d5ac70f0Sopenharmony_ci */
3758d5ac70f0Sopenharmony_ciint snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
3759d5ac70f0Sopenharmony_ci{
3760d5ac70f0Sopenharmony_ci	assert(info);
3761d5ac70f0Sopenharmony_ci	return info->queue;
3762d5ac70f0Sopenharmony_ci}
3763d5ac70f0Sopenharmony_ci
3764d5ac70f0Sopenharmony_ci/**
3765d5ac70f0Sopenharmony_ci * \brief Get the tempo of a queue_status container
3766d5ac70f0Sopenharmony_ci * \param info queue_status container
3767d5ac70f0Sopenharmony_ci * \return tempo value
3768d5ac70f0Sopenharmony_ci *
3769d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3770d5ac70f0Sopenharmony_ci */
3771d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
3772d5ac70f0Sopenharmony_ci{
3773d5ac70f0Sopenharmony_ci	assert(info);
3774d5ac70f0Sopenharmony_ci	return info->tempo;
3775d5ac70f0Sopenharmony_ci}
3776d5ac70f0Sopenharmony_ci
3777d5ac70f0Sopenharmony_ci/**
3778d5ac70f0Sopenharmony_ci * \brief Get the ppq of a queue_status container
3779d5ac70f0Sopenharmony_ci * \param info queue_status container
3780d5ac70f0Sopenharmony_ci * \return ppq value
3781d5ac70f0Sopenharmony_ci *
3782d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3783d5ac70f0Sopenharmony_ci */
3784d5ac70f0Sopenharmony_ciint snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
3785d5ac70f0Sopenharmony_ci{
3786d5ac70f0Sopenharmony_ci	assert(info);
3787d5ac70f0Sopenharmony_ci	return info->ppq;
3788d5ac70f0Sopenharmony_ci}
3789d5ac70f0Sopenharmony_ci
3790d5ac70f0Sopenharmony_ci/**
3791d5ac70f0Sopenharmony_ci * \brief Get the timer skew value of a queue_status container
3792d5ac70f0Sopenharmony_ci * \param info queue_status container
3793d5ac70f0Sopenharmony_ci * \return timer skew value
3794d5ac70f0Sopenharmony_ci *
3795d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3796d5ac70f0Sopenharmony_ci */
3797d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info)
3798d5ac70f0Sopenharmony_ci{
3799d5ac70f0Sopenharmony_ci	assert(info);
3800d5ac70f0Sopenharmony_ci	return info->skew_value;
3801d5ac70f0Sopenharmony_ci}
3802d5ac70f0Sopenharmony_ci
3803d5ac70f0Sopenharmony_ci/**
3804d5ac70f0Sopenharmony_ci * \brief Get the timer skew base value of a queue_status container
3805d5ac70f0Sopenharmony_ci * \param info queue_status container
3806d5ac70f0Sopenharmony_ci * \return timer skew base value
3807d5ac70f0Sopenharmony_ci *
3808d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3809d5ac70f0Sopenharmony_ci */
3810d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info)
3811d5ac70f0Sopenharmony_ci{
3812d5ac70f0Sopenharmony_ci	assert(info);
3813d5ac70f0Sopenharmony_ci	return info->skew_base;
3814d5ac70f0Sopenharmony_ci}
3815d5ac70f0Sopenharmony_ci
3816d5ac70f0Sopenharmony_ci/**
3817d5ac70f0Sopenharmony_ci * \brief Set the tempo of a queue_status container
3818d5ac70f0Sopenharmony_ci * \param info queue_status container
3819d5ac70f0Sopenharmony_ci * \param tempo tempo value
3820d5ac70f0Sopenharmony_ci *
3821d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3822d5ac70f0Sopenharmony_ci */
3823d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
3824d5ac70f0Sopenharmony_ci{
3825d5ac70f0Sopenharmony_ci	assert(info);
3826d5ac70f0Sopenharmony_ci	info->tempo = tempo;
3827d5ac70f0Sopenharmony_ci}
3828d5ac70f0Sopenharmony_ci
3829d5ac70f0Sopenharmony_ci/**
3830d5ac70f0Sopenharmony_ci * \brief Set the ppq of a queue_status container
3831d5ac70f0Sopenharmony_ci * \param info queue_status container
3832d5ac70f0Sopenharmony_ci * \param ppq ppq value
3833d5ac70f0Sopenharmony_ci *
3834d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3835d5ac70f0Sopenharmony_ci */
3836d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
3837d5ac70f0Sopenharmony_ci{
3838d5ac70f0Sopenharmony_ci	assert(info);
3839d5ac70f0Sopenharmony_ci	info->ppq = ppq;
3840d5ac70f0Sopenharmony_ci}
3841d5ac70f0Sopenharmony_ci
3842d5ac70f0Sopenharmony_ci/**
3843d5ac70f0Sopenharmony_ci * \brief Set the timer skew value of a queue_status container
3844d5ac70f0Sopenharmony_ci * \param info queue_status container
3845d5ac70f0Sopenharmony_ci * \param skew timer skew value
3846d5ac70f0Sopenharmony_ci *
3847d5ac70f0Sopenharmony_ci * The skew of timer is calculated as skew / base.
3848d5ac70f0Sopenharmony_ci * For example, to play with double speed, pass base * 2 as the skew value.
3849d5ac70f0Sopenharmony_ci *
3850d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3851d5ac70f0Sopenharmony_ci */
3852d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew)
3853d5ac70f0Sopenharmony_ci{
3854d5ac70f0Sopenharmony_ci	assert(info);
3855d5ac70f0Sopenharmony_ci	info->skew_value = skew;
3856d5ac70f0Sopenharmony_ci}
3857d5ac70f0Sopenharmony_ci
3858d5ac70f0Sopenharmony_ci/**
3859d5ac70f0Sopenharmony_ci * \brief Set the timer skew base value of a queue_status container
3860d5ac70f0Sopenharmony_ci * \param info queue_status container
3861d5ac70f0Sopenharmony_ci * \param base timer skew base value
3862d5ac70f0Sopenharmony_ci *
3863d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3864d5ac70f0Sopenharmony_ci */
3865d5ac70f0Sopenharmony_civoid snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base)
3866d5ac70f0Sopenharmony_ci{
3867d5ac70f0Sopenharmony_ci	assert(info);
3868d5ac70f0Sopenharmony_ci	info->skew_base = base;
3869d5ac70f0Sopenharmony_ci}
3870d5ac70f0Sopenharmony_ci
3871d5ac70f0Sopenharmony_ci/**
3872d5ac70f0Sopenharmony_ci * \brief obtain the current tempo of the queue
3873d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3874d5ac70f0Sopenharmony_ci * \param q queue id to be queried
3875d5ac70f0Sopenharmony_ci * \param tempo pointer to store the current tempo
3876d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3877d5ac70f0Sopenharmony_ci *
3878d5ac70f0Sopenharmony_ci * \sa snd_seq_set_queue_tempo()
3879d5ac70f0Sopenharmony_ci */
3880d5ac70f0Sopenharmony_ciint snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3881d5ac70f0Sopenharmony_ci{
3882d5ac70f0Sopenharmony_ci	assert(seq && tempo);
3883d5ac70f0Sopenharmony_ci	memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
3884d5ac70f0Sopenharmony_ci	tempo->queue = q;
3885d5ac70f0Sopenharmony_ci	return seq->ops->get_queue_tempo(seq, tempo);
3886d5ac70f0Sopenharmony_ci}
3887d5ac70f0Sopenharmony_ci
3888d5ac70f0Sopenharmony_ci/**
3889d5ac70f0Sopenharmony_ci * \brief set the tempo of the queue
3890d5ac70f0Sopenharmony_ci * \param seq sequencer handle
3891d5ac70f0Sopenharmony_ci * \param q queue id to change the tempo
3892d5ac70f0Sopenharmony_ci * \param tempo tempo information
3893d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
3894d5ac70f0Sopenharmony_ci *
3895d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_tempo()
3896d5ac70f0Sopenharmony_ci */
3897d5ac70f0Sopenharmony_ciint snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3898d5ac70f0Sopenharmony_ci{
3899d5ac70f0Sopenharmony_ci	assert(seq && tempo);
3900d5ac70f0Sopenharmony_ci	tempo->queue = q;
3901d5ac70f0Sopenharmony_ci	return seq->ops->set_queue_tempo(seq, tempo);
3902d5ac70f0Sopenharmony_ci}
3903d5ac70f0Sopenharmony_ci
3904d5ac70f0Sopenharmony_ci
3905d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
3906d5ac70f0Sopenharmony_ci
3907d5ac70f0Sopenharmony_ci/**
3908d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_queue_timer_t
3909d5ac70f0Sopenharmony_ci * \return size in bytes
3910d5ac70f0Sopenharmony_ci */
3911d5ac70f0Sopenharmony_cisize_t snd_seq_queue_timer_sizeof()
3912d5ac70f0Sopenharmony_ci{
3913d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_queue_timer_t);
3914d5ac70f0Sopenharmony_ci}
3915d5ac70f0Sopenharmony_ci
3916d5ac70f0Sopenharmony_ci/**
3917d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
3918d5ac70f0Sopenharmony_ci * \param ptr returned pointer
3919d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
3920d5ac70f0Sopenharmony_ci */
3921d5ac70f0Sopenharmony_ciint snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
3922d5ac70f0Sopenharmony_ci{
3923d5ac70f0Sopenharmony_ci	assert(ptr);
3924d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
3925d5ac70f0Sopenharmony_ci	if (!*ptr)
3926d5ac70f0Sopenharmony_ci		return -ENOMEM;
3927d5ac70f0Sopenharmony_ci	return 0;
3928d5ac70f0Sopenharmony_ci}
3929d5ac70f0Sopenharmony_ci
3930d5ac70f0Sopenharmony_ci/**
3931d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_queue_timer_t
3932d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
3933d5ac70f0Sopenharmony_ci */
3934d5ac70f0Sopenharmony_civoid snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
3935d5ac70f0Sopenharmony_ci{
3936d5ac70f0Sopenharmony_ci	free(obj);
3937d5ac70f0Sopenharmony_ci}
3938d5ac70f0Sopenharmony_ci
3939d5ac70f0Sopenharmony_ci/**
3940d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_queue_timer_t to another
3941d5ac70f0Sopenharmony_ci * \param dst pointer to destination
3942d5ac70f0Sopenharmony_ci * \param src pointer to source
3943d5ac70f0Sopenharmony_ci */
3944d5ac70f0Sopenharmony_civoid snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
3945d5ac70f0Sopenharmony_ci{
3946d5ac70f0Sopenharmony_ci	assert(dst && src);
3947d5ac70f0Sopenharmony_ci	*dst = *src;
3948d5ac70f0Sopenharmony_ci}
3949d5ac70f0Sopenharmony_ci
3950d5ac70f0Sopenharmony_ci
3951d5ac70f0Sopenharmony_ci/**
3952d5ac70f0Sopenharmony_ci * \brief Get the queue id of a queue_timer container
3953d5ac70f0Sopenharmony_ci * \param info queue_timer container
3954d5ac70f0Sopenharmony_ci * \return queue id
3955d5ac70f0Sopenharmony_ci *
3956d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
3957d5ac70f0Sopenharmony_ci */
3958d5ac70f0Sopenharmony_ciint snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
3959d5ac70f0Sopenharmony_ci{
3960d5ac70f0Sopenharmony_ci	assert(info);
3961d5ac70f0Sopenharmony_ci	return info->queue;
3962d5ac70f0Sopenharmony_ci}
3963d5ac70f0Sopenharmony_ci
3964d5ac70f0Sopenharmony_ci/**
3965d5ac70f0Sopenharmony_ci * \brief Get the timer type of a queue_timer container
3966d5ac70f0Sopenharmony_ci * \param info queue_timer container
3967d5ac70f0Sopenharmony_ci * \return timer type
3968d5ac70f0Sopenharmony_ci *
3969d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
3970d5ac70f0Sopenharmony_ci */
3971d5ac70f0Sopenharmony_cisnd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
3972d5ac70f0Sopenharmony_ci{
3973d5ac70f0Sopenharmony_ci	assert(info);
3974d5ac70f0Sopenharmony_ci	return (snd_seq_queue_timer_type_t)info->type;
3975d5ac70f0Sopenharmony_ci}
3976d5ac70f0Sopenharmony_ci
3977d5ac70f0Sopenharmony_ci/**
3978d5ac70f0Sopenharmony_ci * \brief Get the timer id of a queue_timer container
3979d5ac70f0Sopenharmony_ci * \param info queue_timer container
3980d5ac70f0Sopenharmony_ci * \return timer id pointer
3981d5ac70f0Sopenharmony_ci *
3982d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
3983d5ac70f0Sopenharmony_ci */
3984d5ac70f0Sopenharmony_ciconst snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
3985d5ac70f0Sopenharmony_ci{
3986d5ac70f0Sopenharmony_ci	assert(info);
3987d5ac70f0Sopenharmony_ci	return &info->u.alsa.id;
3988d5ac70f0Sopenharmony_ci}
3989d5ac70f0Sopenharmony_ci
3990d5ac70f0Sopenharmony_ci/**
3991d5ac70f0Sopenharmony_ci * \brief Get the timer resolution of a queue_timer container
3992d5ac70f0Sopenharmony_ci * \param info queue_timer container
3993d5ac70f0Sopenharmony_ci * \return timer resolution
3994d5ac70f0Sopenharmony_ci *
3995d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
3996d5ac70f0Sopenharmony_ci */
3997d5ac70f0Sopenharmony_ciunsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
3998d5ac70f0Sopenharmony_ci{
3999d5ac70f0Sopenharmony_ci	assert(info);
4000d5ac70f0Sopenharmony_ci	return info->u.alsa.resolution;
4001d5ac70f0Sopenharmony_ci}
4002d5ac70f0Sopenharmony_ci
4003d5ac70f0Sopenharmony_ci/**
4004d5ac70f0Sopenharmony_ci * \brief Set the timer type of a queue_timer container
4005d5ac70f0Sopenharmony_ci * \param info queue_timer container
4006d5ac70f0Sopenharmony_ci * \param type timer type
4007d5ac70f0Sopenharmony_ci *
4008d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
4009d5ac70f0Sopenharmony_ci */
4010d5ac70f0Sopenharmony_civoid snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type)
4011d5ac70f0Sopenharmony_ci{
4012d5ac70f0Sopenharmony_ci	assert(info);
4013d5ac70f0Sopenharmony_ci	info->type = (int)type;
4014d5ac70f0Sopenharmony_ci}
4015d5ac70f0Sopenharmony_ci
4016d5ac70f0Sopenharmony_ci/**
4017d5ac70f0Sopenharmony_ci * \brief Set the timer id of a queue_timer container
4018d5ac70f0Sopenharmony_ci * \param info queue_timer container
4019d5ac70f0Sopenharmony_ci * \param id timer id pointer
4020d5ac70f0Sopenharmony_ci *
4021d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
4022d5ac70f0Sopenharmony_ci */
4023d5ac70f0Sopenharmony_civoid snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
4024d5ac70f0Sopenharmony_ci{
4025d5ac70f0Sopenharmony_ci	assert(info && id);
4026d5ac70f0Sopenharmony_ci	info->u.alsa.id = *id;
4027d5ac70f0Sopenharmony_ci}
4028d5ac70f0Sopenharmony_ci
4029d5ac70f0Sopenharmony_ci/**
4030d5ac70f0Sopenharmony_ci * \brief Set the timer resolution of a queue_timer container
4031d5ac70f0Sopenharmony_ci * \param info queue_timer container
4032d5ac70f0Sopenharmony_ci * \param resolution timer resolution
4033d5ac70f0Sopenharmony_ci *
4034d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
4035d5ac70f0Sopenharmony_ci */
4036d5ac70f0Sopenharmony_civoid snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
4037d5ac70f0Sopenharmony_ci{
4038d5ac70f0Sopenharmony_ci	assert(info);
4039d5ac70f0Sopenharmony_ci	info->u.alsa.resolution = resolution;
4040d5ac70f0Sopenharmony_ci}
4041d5ac70f0Sopenharmony_ci
4042d5ac70f0Sopenharmony_ci
4043d5ac70f0Sopenharmony_ci/**
4044d5ac70f0Sopenharmony_ci * \brief obtain the queue timer information
4045d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4046d5ac70f0Sopenharmony_ci * \param q queue id to query
4047d5ac70f0Sopenharmony_ci * \param timer pointer to store the timer information
4048d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
4049d5ac70f0Sopenharmony_ci *
4050d5ac70f0Sopenharmony_ci * \sa snd_seq_set_queue_timer()
4051d5ac70f0Sopenharmony_ci */
4052d5ac70f0Sopenharmony_ciint snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
4053d5ac70f0Sopenharmony_ci{
4054d5ac70f0Sopenharmony_ci	assert(seq && timer);
4055d5ac70f0Sopenharmony_ci	memset(timer, 0, sizeof(snd_seq_queue_timer_t));
4056d5ac70f0Sopenharmony_ci	timer->queue = q;
4057d5ac70f0Sopenharmony_ci	return seq->ops->get_queue_timer(seq, timer);
4058d5ac70f0Sopenharmony_ci}
4059d5ac70f0Sopenharmony_ci
4060d5ac70f0Sopenharmony_ci/**
4061d5ac70f0Sopenharmony_ci * \brief set the queue timer information
4062d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4063d5ac70f0Sopenharmony_ci * \param q queue id to change the timer
4064d5ac70f0Sopenharmony_ci * \param timer timer information
4065d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
4066d5ac70f0Sopenharmony_ci *
4067d5ac70f0Sopenharmony_ci * \sa snd_seq_get_queue_timer()
4068d5ac70f0Sopenharmony_ci */
4069d5ac70f0Sopenharmony_ciint snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
4070d5ac70f0Sopenharmony_ci{
4071d5ac70f0Sopenharmony_ci	assert(seq && timer);
4072d5ac70f0Sopenharmony_ci	timer->queue = q;
4073d5ac70f0Sopenharmony_ci	return seq->ops->set_queue_timer(seq, timer);
4074d5ac70f0Sopenharmony_ci}
4075d5ac70f0Sopenharmony_ci
4076d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
4077d5ac70f0Sopenharmony_ci
4078d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN
4079d5ac70f0Sopenharmony_ci/**
4080d5ac70f0Sopenharmony_ci * \brief (DEPRECATED) create an event cell
4081d5ac70f0Sopenharmony_ci * \return the cell pointer allocated
4082d5ac70f0Sopenharmony_ci *
4083d5ac70f0Sopenharmony_ci * create an event cell via malloc.  the returned pointer must be released
4084d5ac70f0Sopenharmony_ci * by the application itself via normal free() call,
4085d5ac70f0Sopenharmony_ci * not via snd_seq_free_event().
4086d5ac70f0Sopenharmony_ci */
4087d5ac70f0Sopenharmony_cisnd_seq_event_t *snd_seq_create_event(void)
4088d5ac70f0Sopenharmony_ci{
4089d5ac70f0Sopenharmony_ci	return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
4090d5ac70f0Sopenharmony_ci}
4091d5ac70f0Sopenharmony_ci#endif
4092d5ac70f0Sopenharmony_ci
4093d5ac70f0Sopenharmony_ci/**
4094d5ac70f0Sopenharmony_ci * \brief (DEPRECATED) free an event
4095d5ac70f0Sopenharmony_ci *
4096d5ac70f0Sopenharmony_ci * In the former version, this function was used to
4097d5ac70f0Sopenharmony_ci * release the event pointer which was allocated by snd_seq_event_input().
4098d5ac70f0Sopenharmony_ci * In the current version, the event record is not allocated, so
4099d5ac70f0Sopenharmony_ci * you don't have to call this function any more.
4100d5ac70f0Sopenharmony_ci */
4101d5ac70f0Sopenharmony_ci#ifndef DOXYGEN
4102d5ac70f0Sopenharmony_ciint snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
4103d5ac70f0Sopenharmony_ci#else
4104d5ac70f0Sopenharmony_ciint snd_seq_free_event(snd_seq_event_t *ev)
4105d5ac70f0Sopenharmony_ci#endif
4106d5ac70f0Sopenharmony_ci{
4107d5ac70f0Sopenharmony_ci	return 0;
4108d5ac70f0Sopenharmony_ci}
4109d5ac70f0Sopenharmony_ci
4110d5ac70f0Sopenharmony_ci/**
4111d5ac70f0Sopenharmony_ci * \brief calculates the (encoded) byte-stream size of the event
4112d5ac70f0Sopenharmony_ci * \param ev the event
4113d5ac70f0Sopenharmony_ci * \return the size of decoded bytes
4114d5ac70f0Sopenharmony_ci */
4115d5ac70f0Sopenharmony_cissize_t snd_seq_event_length(snd_seq_event_t *ev)
4116d5ac70f0Sopenharmony_ci{
4117d5ac70f0Sopenharmony_ci	ssize_t len = sizeof(snd_seq_event_t);
4118d5ac70f0Sopenharmony_ci	assert(ev);
4119d5ac70f0Sopenharmony_ci	if (snd_seq_ev_is_ump(ev))
4120d5ac70f0Sopenharmony_ci		len = sizeof(snd_seq_ump_event_t);
4121d5ac70f0Sopenharmony_ci	else if (snd_seq_ev_is_variable(ev))
4122d5ac70f0Sopenharmony_ci		len += ev->data.ext.len;
4123d5ac70f0Sopenharmony_ci	return len;
4124d5ac70f0Sopenharmony_ci}
4125d5ac70f0Sopenharmony_ci
4126d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
4127d5ac70f0Sopenharmony_ci
4128d5ac70f0Sopenharmony_ci/*
4129d5ac70f0Sopenharmony_ci * output to sequencer
4130d5ac70f0Sopenharmony_ci */
4131d5ac70f0Sopenharmony_ci
4132d5ac70f0Sopenharmony_ci/**
4133d5ac70f0Sopenharmony_ci * \brief output an event
4134d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4135d5ac70f0Sopenharmony_ci * \param ev event to be output
4136d5ac70f0Sopenharmony_ci * \return the number of remaining events or a negative error code
4137d5ac70f0Sopenharmony_ci *
4138d5ac70f0Sopenharmony_ci * An event is once expanded on the output buffer.
4139d5ac70f0Sopenharmony_ci * The output buffer will be drained automatically if it becomes full.
4140d5ac70f0Sopenharmony_ci *
4141d5ac70f0Sopenharmony_ci * If events remain unprocessed on output buffer before drained,
4142d5ac70f0Sopenharmony_ci * the size of total byte data on output buffer is returned.
4143d5ac70f0Sopenharmony_ci * If the output buffer is empty, this returns zero.
4144d5ac70f0Sopenharmony_ci *
4145d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output_direct(), snd_seq_event_output_buffer(),
4146d5ac70f0Sopenharmony_ci *    snd_seq_event_output_pending(), snd_seq_drain_output(),
4147d5ac70f0Sopenharmony_ci *    snd_seq_drop_output(), snd_seq_extract_output(),
4148d5ac70f0Sopenharmony_ci *    snd_seq_remove_events()
4149d5ac70f0Sopenharmony_ci */
4150d5ac70f0Sopenharmony_ciint snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
4151d5ac70f0Sopenharmony_ci{
4152d5ac70f0Sopenharmony_ci	int result;
4153d5ac70f0Sopenharmony_ci
4154d5ac70f0Sopenharmony_ci	result = snd_seq_event_output_buffer(seq, ev);
4155d5ac70f0Sopenharmony_ci	if (result == -EAGAIN) {
4156d5ac70f0Sopenharmony_ci		result = snd_seq_drain_output(seq);
4157d5ac70f0Sopenharmony_ci		if (result < 0)
4158d5ac70f0Sopenharmony_ci			return result;
4159d5ac70f0Sopenharmony_ci		return snd_seq_event_output_buffer(seq, ev);
4160d5ac70f0Sopenharmony_ci	}
4161d5ac70f0Sopenharmony_ci	return result;
4162d5ac70f0Sopenharmony_ci}
4163d5ac70f0Sopenharmony_ci
4164d5ac70f0Sopenharmony_ci/* workaround for broken legacy apps that set UMP event bit unexpectedly */
4165d5ac70f0Sopenharmony_cistatic void clear_ump_for_legacy_apps(snd_seq_t *seq, snd_seq_event_t *ev)
4166d5ac70f0Sopenharmony_ci{
4167d5ac70f0Sopenharmony_ci	if (!seq->midi_version && snd_seq_ev_is_ump(ev))
4168d5ac70f0Sopenharmony_ci		ev->flags &= ~SNDRV_SEQ_EVENT_UMP;
4169d5ac70f0Sopenharmony_ci}
4170d5ac70f0Sopenharmony_ci
4171d5ac70f0Sopenharmony_ci/**
4172d5ac70f0Sopenharmony_ci * \brief output an event onto the lib buffer without draining buffer
4173d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4174d5ac70f0Sopenharmony_ci * \param ev event to be output
4175d5ac70f0Sopenharmony_ci * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
4176d5ac70f0Sopenharmony_ci *
4177d5ac70f0Sopenharmony_ci * This function doesn't drain buffer unlike snd_seq_event_output().
4178d5ac70f0Sopenharmony_ci *
4179d5ac70f0Sopenharmony_ci * \note
4180d5ac70f0Sopenharmony_ci * For a UMP event, use snd_seq_ump_event_output_buffer() instead.
4181d5ac70f0Sopenharmony_ci *
4182d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output(), snd_seq_ump_event_output_buffer()
4183d5ac70f0Sopenharmony_ci */
4184d5ac70f0Sopenharmony_ciint snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
4185d5ac70f0Sopenharmony_ci{
4186d5ac70f0Sopenharmony_ci	int len;
4187d5ac70f0Sopenharmony_ci	assert(seq && ev);
4188d5ac70f0Sopenharmony_ci	clear_ump_for_legacy_apps(seq, ev);
4189d5ac70f0Sopenharmony_ci	len = snd_seq_event_length(ev);
4190d5ac70f0Sopenharmony_ci	if (len < 0)
4191d5ac70f0Sopenharmony_ci		return -EINVAL;
4192d5ac70f0Sopenharmony_ci	if ((size_t) len >= seq->obufsize)
4193d5ac70f0Sopenharmony_ci		return -EINVAL;
4194d5ac70f0Sopenharmony_ci	if ((seq->obufsize - seq->obufused) < (size_t) len)
4195d5ac70f0Sopenharmony_ci		return -EAGAIN;
4196d5ac70f0Sopenharmony_ci	if (snd_seq_ev_is_ump(ev)) {
4197d5ac70f0Sopenharmony_ci		memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_ump_event_t));
4198d5ac70f0Sopenharmony_ci	} else {
4199d5ac70f0Sopenharmony_ci		memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
4200d5ac70f0Sopenharmony_ci		if (snd_seq_ev_is_variable(ev))
4201d5ac70f0Sopenharmony_ci			memcpy(seq->obuf + seq->obufused + sizeof(snd_seq_event_t),
4202d5ac70f0Sopenharmony_ci			       ev->data.ext.ptr, ev->data.ext.len);
4203d5ac70f0Sopenharmony_ci	}
4204d5ac70f0Sopenharmony_ci	seq->obufused += len;
4205d5ac70f0Sopenharmony_ci	return seq->obufused;
4206d5ac70f0Sopenharmony_ci}
4207d5ac70f0Sopenharmony_ci
4208d5ac70f0Sopenharmony_ci/*
4209d5ac70f0Sopenharmony_ci * allocate the temporary buffer
4210d5ac70f0Sopenharmony_ci */
4211d5ac70f0Sopenharmony_cistatic int alloc_tmpbuf(snd_seq_t *seq, size_t len)
4212d5ac70f0Sopenharmony_ci{
4213d5ac70f0Sopenharmony_ci	size_t size = ((len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t));
4214d5ac70f0Sopenharmony_ci	if (seq->tmpbuf == NULL) {
4215d5ac70f0Sopenharmony_ci		if (size > DEFAULT_TMPBUF_SIZE)
4216d5ac70f0Sopenharmony_ci			seq->tmpbufsize = size;
4217d5ac70f0Sopenharmony_ci		else
4218d5ac70f0Sopenharmony_ci			seq->tmpbufsize = DEFAULT_TMPBUF_SIZE;
4219d5ac70f0Sopenharmony_ci		seq->tmpbuf = malloc(seq->tmpbufsize * sizeof(snd_seq_event_t));
4220d5ac70f0Sopenharmony_ci		if (seq->tmpbuf == NULL)
4221d5ac70f0Sopenharmony_ci			return -ENOMEM;
4222d5ac70f0Sopenharmony_ci	}  else if (len > seq->tmpbufsize) {
4223d5ac70f0Sopenharmony_ci		seq->tmpbuf = realloc(seq->tmpbuf, size * sizeof(snd_seq_event_t));
4224d5ac70f0Sopenharmony_ci		if (seq->tmpbuf == NULL)
4225d5ac70f0Sopenharmony_ci			return -ENOMEM;
4226d5ac70f0Sopenharmony_ci		seq->tmpbufsize = size;
4227d5ac70f0Sopenharmony_ci	}
4228d5ac70f0Sopenharmony_ci	return 0;
4229d5ac70f0Sopenharmony_ci}
4230d5ac70f0Sopenharmony_ci
4231d5ac70f0Sopenharmony_ci/**
4232d5ac70f0Sopenharmony_ci * \brief output an event directly to the sequencer NOT through output buffer
4233d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4234d5ac70f0Sopenharmony_ci * \param ev event to be output
4235d5ac70f0Sopenharmony_ci * \return the byte size sent to sequencer or a negative error code
4236d5ac70f0Sopenharmony_ci *
4237d5ac70f0Sopenharmony_ci * This function sends an event to the sequencer directly not through the
4238d5ac70f0Sopenharmony_ci * output buffer.  When the event is a variable length event, a temporary
4239d5ac70f0Sopenharmony_ci * buffer is allocated inside alsa-lib and the data is copied there before
4240d5ac70f0Sopenharmony_ci * actually sent.
4241d5ac70f0Sopenharmony_ci *
4242d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output()
4243d5ac70f0Sopenharmony_ci */
4244d5ac70f0Sopenharmony_ciint snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
4245d5ac70f0Sopenharmony_ci{
4246d5ac70f0Sopenharmony_ci	ssize_t len;
4247d5ac70f0Sopenharmony_ci	void *buf;
4248d5ac70f0Sopenharmony_ci
4249d5ac70f0Sopenharmony_ci	clear_ump_for_legacy_apps(seq, ev);
4250d5ac70f0Sopenharmony_ci	len = snd_seq_event_length(ev);
4251d5ac70f0Sopenharmony_ci	if (len < 0)
4252d5ac70f0Sopenharmony_ci		return len;
4253d5ac70f0Sopenharmony_ci	if (snd_seq_ev_is_ump(ev) || !snd_seq_ev_is_variable(ev)) {
4254d5ac70f0Sopenharmony_ci		buf = ev;
4255d5ac70f0Sopenharmony_ci	} else {
4256d5ac70f0Sopenharmony_ci		if (alloc_tmpbuf(seq, (size_t)len) < 0)
4257d5ac70f0Sopenharmony_ci			return -ENOMEM;
4258d5ac70f0Sopenharmony_ci		*seq->tmpbuf = *ev;
4259d5ac70f0Sopenharmony_ci		memcpy(seq->tmpbuf + 1, ev->data.ext.ptr, ev->data.ext.len);
4260d5ac70f0Sopenharmony_ci		buf = seq->tmpbuf;
4261d5ac70f0Sopenharmony_ci	}
4262d5ac70f0Sopenharmony_ci	return seq->ops->write(seq, buf, (size_t) len);
4263d5ac70f0Sopenharmony_ci}
4264d5ac70f0Sopenharmony_ci
4265d5ac70f0Sopenharmony_ci/**
4266d5ac70f0Sopenharmony_ci * \brief return the size of pending events on output buffer
4267d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4268d5ac70f0Sopenharmony_ci * \return the byte size of total of pending events
4269d5ac70f0Sopenharmony_ci *
4270d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output()
4271d5ac70f0Sopenharmony_ci */
4272d5ac70f0Sopenharmony_ciint snd_seq_event_output_pending(snd_seq_t *seq)
4273d5ac70f0Sopenharmony_ci{
4274d5ac70f0Sopenharmony_ci	assert(seq);
4275d5ac70f0Sopenharmony_ci	return seq->obufused;
4276d5ac70f0Sopenharmony_ci}
4277d5ac70f0Sopenharmony_ci
4278d5ac70f0Sopenharmony_ci/**
4279d5ac70f0Sopenharmony_ci * \brief drain output buffer to sequencer
4280d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4281d5ac70f0Sopenharmony_ci * \return 0 when all events are drained and sent to sequencer.
4282d5ac70f0Sopenharmony_ci *         When events still remain on the buffer, the byte size of remaining
4283d5ac70f0Sopenharmony_ci *         events are returned.  On error a negative error code is returned.
4284d5ac70f0Sopenharmony_ci *
4285d5ac70f0Sopenharmony_ci * This function drains all pending events on the output buffer.
4286d5ac70f0Sopenharmony_ci * The function returns immediately after the events are sent to the queues
4287d5ac70f0Sopenharmony_ci * regardless whether the events are processed or not.
4288d5ac70f0Sopenharmony_ci * To get synchronization with the all event processes, use
4289d5ac70f0Sopenharmony_ci * #snd_seq_sync_output_queue() after calling this function.
4290d5ac70f0Sopenharmony_ci *
4291d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output(), snd_seq_sync_output_queue()
4292d5ac70f0Sopenharmony_ci */
4293d5ac70f0Sopenharmony_ciint snd_seq_drain_output(snd_seq_t *seq)
4294d5ac70f0Sopenharmony_ci{
4295d5ac70f0Sopenharmony_ci	ssize_t result, processed = 0;
4296d5ac70f0Sopenharmony_ci	assert(seq);
4297d5ac70f0Sopenharmony_ci	while (seq->obufused > 0) {
4298d5ac70f0Sopenharmony_ci		result = seq->ops->write(seq, seq->obuf, seq->obufused);
4299d5ac70f0Sopenharmony_ci		if (result < 0) {
4300d5ac70f0Sopenharmony_ci			if (result == -EAGAIN && processed)
4301d5ac70f0Sopenharmony_ci				return seq->obufused;
4302d5ac70f0Sopenharmony_ci			return result;
4303d5ac70f0Sopenharmony_ci		}
4304d5ac70f0Sopenharmony_ci		if ((size_t)result < seq->obufused)
4305d5ac70f0Sopenharmony_ci			memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
4306d5ac70f0Sopenharmony_ci		seq->obufused -= result;
4307d5ac70f0Sopenharmony_ci	}
4308d5ac70f0Sopenharmony_ci	return 0;
4309d5ac70f0Sopenharmony_ci}
4310d5ac70f0Sopenharmony_ci
4311d5ac70f0Sopenharmony_ci/**
4312d5ac70f0Sopenharmony_ci * \brief extract the first event in output buffer
4313d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4314d5ac70f0Sopenharmony_ci * \param ev_res event pointer to be extracted
4315d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
4316d5ac70f0Sopenharmony_ci *
4317d5ac70f0Sopenharmony_ci * Extracts the first event in output buffer.
4318d5ac70f0Sopenharmony_ci * If ev_res is NULL, just remove the event.
4319d5ac70f0Sopenharmony_ci *
4320d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output()
4321d5ac70f0Sopenharmony_ci */
4322d5ac70f0Sopenharmony_ciint snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
4323d5ac70f0Sopenharmony_ci{
4324d5ac70f0Sopenharmony_ci	size_t len, olen;
4325d5ac70f0Sopenharmony_ci	assert(seq);
4326d5ac70f0Sopenharmony_ci	if (ev_res)
4327d5ac70f0Sopenharmony_ci		*ev_res = NULL;
4328d5ac70f0Sopenharmony_ci	if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
4329d5ac70f0Sopenharmony_ci		return -ENOENT;
4330d5ac70f0Sopenharmony_ci	len = snd_seq_event_length((snd_seq_event_t *)seq->obuf);
4331d5ac70f0Sopenharmony_ci	if (olen < len)
4332d5ac70f0Sopenharmony_ci		return -ENOENT;
4333d5ac70f0Sopenharmony_ci	if (ev_res) {
4334d5ac70f0Sopenharmony_ci		/* extract the event */
4335d5ac70f0Sopenharmony_ci		if (alloc_tmpbuf(seq, len) < 0)
4336d5ac70f0Sopenharmony_ci			return -ENOMEM;
4337d5ac70f0Sopenharmony_ci		memcpy(seq->tmpbuf, seq->obuf, len);
4338d5ac70f0Sopenharmony_ci		*ev_res = (snd_seq_event_t *)seq->tmpbuf;
4339d5ac70f0Sopenharmony_ci	}
4340d5ac70f0Sopenharmony_ci	seq->obufused = olen - len;
4341d5ac70f0Sopenharmony_ci	memmove(seq->obuf, seq->obuf + len, seq->obufused);
4342d5ac70f0Sopenharmony_ci	return 0;
4343d5ac70f0Sopenharmony_ci}
4344d5ac70f0Sopenharmony_ci
4345d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
4346d5ac70f0Sopenharmony_ci
4347d5ac70f0Sopenharmony_ci/*
4348d5ac70f0Sopenharmony_ci * input from sequencer
4349d5ac70f0Sopenharmony_ci */
4350d5ac70f0Sopenharmony_ci
4351d5ac70f0Sopenharmony_ci/*
4352d5ac70f0Sopenharmony_ci * read from sequencer to input buffer
4353d5ac70f0Sopenharmony_ci */
4354d5ac70f0Sopenharmony_cistatic ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
4355d5ac70f0Sopenharmony_ci{
4356d5ac70f0Sopenharmony_ci	size_t packet_size = get_packet_size(seq);
4357d5ac70f0Sopenharmony_ci	ssize_t len;
4358d5ac70f0Sopenharmony_ci
4359d5ac70f0Sopenharmony_ci	len = (seq->ops->read)(seq, seq->ibuf, seq->ibufsize * packet_size);
4360d5ac70f0Sopenharmony_ci	if (len < 0)
4361d5ac70f0Sopenharmony_ci		return len;
4362d5ac70f0Sopenharmony_ci	seq->ibuflen = len / packet_size;
4363d5ac70f0Sopenharmony_ci	seq->ibufptr = 0;
4364d5ac70f0Sopenharmony_ci	return seq->ibuflen;
4365d5ac70f0Sopenharmony_ci}
4366d5ac70f0Sopenharmony_ci
4367d5ac70f0Sopenharmony_cistatic int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
4368d5ac70f0Sopenharmony_ci{
4369d5ac70f0Sopenharmony_ci	size_t packet_size = get_packet_size(seq);
4370d5ac70f0Sopenharmony_ci	size_t ncells;
4371d5ac70f0Sopenharmony_ci	snd_seq_event_t *ev;
4372d5ac70f0Sopenharmony_ci
4373d5ac70f0Sopenharmony_ci	*retp = ev = (snd_seq_event_t *)(seq->ibuf + seq->ibufptr * packet_size);
4374d5ac70f0Sopenharmony_ci	clear_ump_for_legacy_apps(seq, ev);
4375d5ac70f0Sopenharmony_ci	seq->ibufptr++;
4376d5ac70f0Sopenharmony_ci	seq->ibuflen--;
4377d5ac70f0Sopenharmony_ci	if (! snd_seq_ev_is_variable(ev))
4378d5ac70f0Sopenharmony_ci		return 1;
4379d5ac70f0Sopenharmony_ci	ncells = (ev->data.ext.len + packet_size - 1) / packet_size;
4380d5ac70f0Sopenharmony_ci	if (seq->ibuflen < ncells) {
4381d5ac70f0Sopenharmony_ci		seq->ibuflen = 0; /* clear buffer */
4382d5ac70f0Sopenharmony_ci		*retp = NULL;
4383d5ac70f0Sopenharmony_ci		return -EINVAL;
4384d5ac70f0Sopenharmony_ci	}
4385d5ac70f0Sopenharmony_ci	ev->data.ext.ptr = (char *)ev + packet_size;
4386d5ac70f0Sopenharmony_ci	seq->ibuflen -= ncells;
4387d5ac70f0Sopenharmony_ci	seq->ibufptr += ncells;
4388d5ac70f0Sopenharmony_ci	return 1;
4389d5ac70f0Sopenharmony_ci}
4390d5ac70f0Sopenharmony_ci
4391d5ac70f0Sopenharmony_ci/**
4392d5ac70f0Sopenharmony_ci * \brief retrieve an event from sequencer
4393d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4394d5ac70f0Sopenharmony_ci * \param ev event pointer to be stored
4395d5ac70f0Sopenharmony_ci * \return
4396d5ac70f0Sopenharmony_ci *
4397d5ac70f0Sopenharmony_ci * Obtains an input event from sequencer.
4398d5ac70f0Sopenharmony_ci * The event is created via snd_seq_create_event(), and its pointer is stored on
4399d5ac70f0Sopenharmony_ci * ev argument.
4400d5ac70f0Sopenharmony_ci *
4401d5ac70f0Sopenharmony_ci * This function firstly receives the event byte-stream data from sequencer
4402d5ac70f0Sopenharmony_ci * as much as possible at once.  Then it retrieves the first event record
4403d5ac70f0Sopenharmony_ci * and store the pointer on ev.
4404d5ac70f0Sopenharmony_ci * By calling this function sequentially, events are extracted from the input buffer.
4405d5ac70f0Sopenharmony_ci *
4406d5ac70f0Sopenharmony_ci * If there is no input from sequencer, function falls into sleep
4407d5ac70f0Sopenharmony_ci * in blocking mode until an event is received,
4408d5ac70f0Sopenharmony_ci * or returns \c -EAGAIN error in non-blocking mode.
4409d5ac70f0Sopenharmony_ci * Occasionally, this function may return \c -ENOSPC error.
4410d5ac70f0Sopenharmony_ci * This means that the input FIFO of sequencer overran, and some events are
4411d5ac70f0Sopenharmony_ci * lost.
4412d5ac70f0Sopenharmony_ci * Once this error is returned, the input FIFO is cleared automatically.
4413d5ac70f0Sopenharmony_ci *
4414d5ac70f0Sopenharmony_ci * Function returns the byte size of remaining events on the input buffer
4415d5ac70f0Sopenharmony_ci * if an event is successfully received.
4416d5ac70f0Sopenharmony_ci * Application can determine from the returned value whether to call
4417d5ac70f0Sopenharmony_ci * input once more or not.
4418d5ac70f0Sopenharmony_ci *
4419d5ac70f0Sopenharmony_ci * \sa snd_seq_event_input_pending(), snd_seq_drop_input()
4420d5ac70f0Sopenharmony_ci */
4421d5ac70f0Sopenharmony_ciint snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
4422d5ac70f0Sopenharmony_ci{
4423d5ac70f0Sopenharmony_ci	int err;
4424d5ac70f0Sopenharmony_ci	assert(seq);
4425d5ac70f0Sopenharmony_ci	*ev = NULL;
4426d5ac70f0Sopenharmony_ci	if (seq->ibuflen <= 0) {
4427d5ac70f0Sopenharmony_ci		if ((err = snd_seq_event_read_buffer(seq)) < 0)
4428d5ac70f0Sopenharmony_ci			return err;
4429d5ac70f0Sopenharmony_ci	}
4430d5ac70f0Sopenharmony_ci
4431d5ac70f0Sopenharmony_ci	return snd_seq_event_retrieve_buffer(seq, ev);
4432d5ac70f0Sopenharmony_ci}
4433d5ac70f0Sopenharmony_ci
4434d5ac70f0Sopenharmony_ci/*
4435d5ac70f0Sopenharmony_ci * read input data from sequencer if available
4436d5ac70f0Sopenharmony_ci */
4437d5ac70f0Sopenharmony_cistatic int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
4438d5ac70f0Sopenharmony_ci{
4439d5ac70f0Sopenharmony_ci	struct pollfd pfd;
4440d5ac70f0Sopenharmony_ci	int err;
4441d5ac70f0Sopenharmony_ci	pfd.fd = seq->poll_fd;
4442d5ac70f0Sopenharmony_ci	pfd.events = POLLIN;
4443d5ac70f0Sopenharmony_ci	err = poll(&pfd, 1, timeout);
4444d5ac70f0Sopenharmony_ci	if (err < 0) {
4445d5ac70f0Sopenharmony_ci		SYSERR("poll");
4446d5ac70f0Sopenharmony_ci		return -errno;
4447d5ac70f0Sopenharmony_ci	}
4448d5ac70f0Sopenharmony_ci	if (pfd.revents & POLLIN)
4449d5ac70f0Sopenharmony_ci		return snd_seq_event_read_buffer(seq);
4450d5ac70f0Sopenharmony_ci	return seq->ibuflen;
4451d5ac70f0Sopenharmony_ci}
4452d5ac70f0Sopenharmony_ci
4453d5ac70f0Sopenharmony_ci/**
4454d5ac70f0Sopenharmony_ci * \brief check events in input buffer
4455d5ac70f0Sopenharmony_ci * \return the byte size of remaining input events on input buffer.
4456d5ac70f0Sopenharmony_ci *
4457d5ac70f0Sopenharmony_ci * If events remain on the input buffer of user-space, function returns
4458d5ac70f0Sopenharmony_ci * the total byte size of events on it.
4459d5ac70f0Sopenharmony_ci * If fetch_sequencer argument is non-zero,
4460d5ac70f0Sopenharmony_ci * this function checks the presence of events on sequencer FIFO
4461d5ac70f0Sopenharmony_ci * When events exist, they are transferred to the input buffer,
4462d5ac70f0Sopenharmony_ci * and the number of received events are returned.
4463d5ac70f0Sopenharmony_ci * If fetch_sequencer argument is zero and
4464d5ac70f0Sopenharmony_ci * no events remain on the input buffer, function simply returns zero.
4465d5ac70f0Sopenharmony_ci *
4466d5ac70f0Sopenharmony_ci * \sa snd_seq_event_input()
4467d5ac70f0Sopenharmony_ci */
4468d5ac70f0Sopenharmony_ciint snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
4469d5ac70f0Sopenharmony_ci{
4470d5ac70f0Sopenharmony_ci	if (seq->ibuflen == 0 && fetch_sequencer) {
4471d5ac70f0Sopenharmony_ci		return snd_seq_event_input_feed(seq, 0);
4472d5ac70f0Sopenharmony_ci	}
4473d5ac70f0Sopenharmony_ci	return seq->ibuflen;
4474d5ac70f0Sopenharmony_ci}
4475d5ac70f0Sopenharmony_ci
4476d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
4477d5ac70f0Sopenharmony_ci
4478d5ac70f0Sopenharmony_ci/*
4479d5ac70f0Sopenharmony_ci * I/O for UMP packets
4480d5ac70f0Sopenharmony_ci */
4481d5ac70f0Sopenharmony_ci
4482d5ac70f0Sopenharmony_ci/**
4483d5ac70f0Sopenharmony_ci * \brief output a UMP event
4484d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4485d5ac70f0Sopenharmony_ci * \param ev UMP event to be output
4486d5ac70f0Sopenharmony_ci * \return the number of remaining events or a negative error code
4487d5ac70f0Sopenharmony_ci *
4488d5ac70f0Sopenharmony_ci * Just like snd_seq_event_output(), it puts an event onto the buffer,
4489d5ac70f0Sopenharmony_ci * draining the buffer automatically when needed, but the event is
4490d5ac70f0Sopenharmony_ci * snd_seq_ump_event_t type instead snd_seq_event_t.
4491d5ac70f0Sopenharmony_ci *
4492d5ac70f0Sopenharmony_ci * Calling this function is allowed only when the client is set to
4493d5ac70f0Sopenharmony_ci * \c SND_SEQ_CLIENT_UMP_MIDI_1_0 or \c SND_SEQ_CLIENT_UMP_MIDI_2_0.
4494d5ac70f0Sopenharmony_ci *
4495d5ac70f0Sopenharmony_ci * The flushing and clearing of the buffer is done via the same functions,
4496d5ac70f0Sopenharmony_ci * snd_seq_event_drain_output() and snd_seq_drop_output().
4497d5ac70f0Sopenharmony_ci *
4498d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output()
4499d5ac70f0Sopenharmony_ci */
4500d5ac70f0Sopenharmony_ciint snd_seq_ump_event_output(snd_seq_t *seq, snd_seq_ump_event_t *ev)
4501d5ac70f0Sopenharmony_ci{
4502d5ac70f0Sopenharmony_ci	if (!seq->midi_version)
4503d5ac70f0Sopenharmony_ci		return -EBADFD;
4504d5ac70f0Sopenharmony_ci	return snd_seq_event_output(seq, (snd_seq_event_t *)ev);
4505d5ac70f0Sopenharmony_ci}
4506d5ac70f0Sopenharmony_ci
4507d5ac70f0Sopenharmony_ci/**
4508d5ac70f0Sopenharmony_ci * \brief output an event onto the lib buffer without draining buffer
4509d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4510d5ac70f0Sopenharmony_ci * \param ev UMP event to be output
4511d5ac70f0Sopenharmony_ci * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
4512d5ac70f0Sopenharmony_ci *
4513d5ac70f0Sopenharmony_ci * This is a UMP event version of snd_seq_event_output_buffer().
4514d5ac70f0Sopenharmony_ci *
4515d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output_buffer(), snd_seq_ump_event_output()
4516d5ac70f0Sopenharmony_ci */
4517d5ac70f0Sopenharmony_ciint snd_seq_ump_event_output_buffer(snd_seq_t *seq, snd_seq_ump_event_t *ev)
4518d5ac70f0Sopenharmony_ci{
4519d5ac70f0Sopenharmony_ci	if (!seq->midi_version)
4520d5ac70f0Sopenharmony_ci		return -EBADFD;
4521d5ac70f0Sopenharmony_ci	return snd_seq_event_output_buffer(seq, (snd_seq_event_t *)ev);
4522d5ac70f0Sopenharmony_ci}
4523d5ac70f0Sopenharmony_ci
4524d5ac70f0Sopenharmony_ci/**
4525d5ac70f0Sopenharmony_ci * \brief extract the first UMP event in output buffer
4526d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4527d5ac70f0Sopenharmony_ci * \param ev_res UMP event pointer to be extracted
4528d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code
4529d5ac70f0Sopenharmony_ci *
4530d5ac70f0Sopenharmony_ci * This is a UMP event version of snd_seq_extract_output().
4531d5ac70f0Sopenharmony_ci *
4532d5ac70f0Sopenharmony_ci * \sa snd_seq_extract_output(), snd_seq_ump_event_output()
4533d5ac70f0Sopenharmony_ci */
4534d5ac70f0Sopenharmony_ciint snd_seq_ump_extract_output(snd_seq_t *seq, snd_seq_ump_event_t **ev_res)
4535d5ac70f0Sopenharmony_ci{
4536d5ac70f0Sopenharmony_ci	if (!seq->midi_version)
4537d5ac70f0Sopenharmony_ci		return -EBADFD;
4538d5ac70f0Sopenharmony_ci	return snd_seq_extract_output(seq, (snd_seq_event_t **)ev_res);
4539d5ac70f0Sopenharmony_ci}
4540d5ac70f0Sopenharmony_ci
4541d5ac70f0Sopenharmony_ci/**
4542d5ac70f0Sopenharmony_ci * \brief output a UMP event directly to the sequencer NOT through output buffer
4543d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4544d5ac70f0Sopenharmony_ci * \param ev UMP event to be output
4545d5ac70f0Sopenharmony_ci * \return the byte size sent to sequencer or a negative error code
4546d5ac70f0Sopenharmony_ci *
4547d5ac70f0Sopenharmony_ci * This is a UMP event version of snd_seq_event_output_direct().
4548d5ac70f0Sopenharmony_ci *
4549d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output_direct()
4550d5ac70f0Sopenharmony_ci */
4551d5ac70f0Sopenharmony_ciint snd_seq_ump_event_output_direct(snd_seq_t *seq, snd_seq_ump_event_t *ev)
4552d5ac70f0Sopenharmony_ci{
4553d5ac70f0Sopenharmony_ci	if (!seq->midi_version)
4554d5ac70f0Sopenharmony_ci		return -EBADFD;
4555d5ac70f0Sopenharmony_ci	return snd_seq_event_output_direct(seq, (snd_seq_event_t *)ev);
4556d5ac70f0Sopenharmony_ci}
4557d5ac70f0Sopenharmony_ci
4558d5ac70f0Sopenharmony_ci/**
4559d5ac70f0Sopenharmony_ci * \brief retrieve a UMP event from sequencer
4560d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4561d5ac70f0Sopenharmony_ci * \param ev UMP event pointer to be stored
4562d5ac70f0Sopenharmony_ci *
4563d5ac70f0Sopenharmony_ci * Like snd_seq_event_input(), this reads out the input event, but in
4564d5ac70f0Sopenharmony_ci * snd_seq_ump_event_t type instead of snd_seq_event_t type.
4565d5ac70f0Sopenharmony_ci *
4566d5ac70f0Sopenharmony_ci * Calling this function is allowed only when the client is set to
4567d5ac70f0Sopenharmony_ci * \c SND_SEQ_CLIENT_UMP_MIDI_1_0 or \c SND_SEQ_CLIENT_UMP_MIDI_2_0.
4568d5ac70f0Sopenharmony_ci *
4569d5ac70f0Sopenharmony_ci * For other input operations, the same function like
4570d5ac70f0Sopenharmony_ci * snd_seq_event_input_pending() or snd_seq_drop_input() can be still used.
4571d5ac70f0Sopenharmony_ci *
4572d5ac70f0Sopenharmony_ci * \sa snd_seq_event_input()
4573d5ac70f0Sopenharmony_ci */
4574d5ac70f0Sopenharmony_ciint snd_seq_ump_event_input(snd_seq_t *seq, snd_seq_ump_event_t **ev)
4575d5ac70f0Sopenharmony_ci{
4576d5ac70f0Sopenharmony_ci	if (!seq->midi_version)
4577d5ac70f0Sopenharmony_ci		return -EBADFD;
4578d5ac70f0Sopenharmony_ci	return snd_seq_event_input(seq, (snd_seq_event_t **)ev);
4579d5ac70f0Sopenharmony_ci}
4580d5ac70f0Sopenharmony_ci
4581d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
4582d5ac70f0Sopenharmony_ci
4583d5ac70f0Sopenharmony_ci/*
4584d5ac70f0Sopenharmony_ci * clear event buffers
4585d5ac70f0Sopenharmony_ci */
4586d5ac70f0Sopenharmony_ci
4587d5ac70f0Sopenharmony_ci/**
4588d5ac70f0Sopenharmony_ci * \brief remove all events on user-space output buffer
4589d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4590d5ac70f0Sopenharmony_ci *
4591d5ac70f0Sopenharmony_ci * Removes all events on user-space output buffer.
4592d5ac70f0Sopenharmony_ci * Unlike snd_seq_drain_output(), this function doesn't remove
4593d5ac70f0Sopenharmony_ci * events on output memory pool of sequencer.
4594d5ac70f0Sopenharmony_ci *
4595d5ac70f0Sopenharmony_ci * \sa snd_seq_drop_output()
4596d5ac70f0Sopenharmony_ci */
4597d5ac70f0Sopenharmony_ciint snd_seq_drop_output_buffer(snd_seq_t *seq)
4598d5ac70f0Sopenharmony_ci{
4599d5ac70f0Sopenharmony_ci	assert(seq);
4600d5ac70f0Sopenharmony_ci	seq->obufused = 0;
4601d5ac70f0Sopenharmony_ci	return 0;
4602d5ac70f0Sopenharmony_ci}
4603d5ac70f0Sopenharmony_ci
4604d5ac70f0Sopenharmony_ci/**
4605d5ac70f0Sopenharmony_ci * \brief remove all events on user-space input FIFO
4606d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4607d5ac70f0Sopenharmony_ci *
4608d5ac70f0Sopenharmony_ci * \sa snd_seq_drop_input()
4609d5ac70f0Sopenharmony_ci */
4610d5ac70f0Sopenharmony_ciint snd_seq_drop_input_buffer(snd_seq_t *seq)
4611d5ac70f0Sopenharmony_ci{
4612d5ac70f0Sopenharmony_ci	assert(seq);
4613d5ac70f0Sopenharmony_ci	seq->ibufptr = 0;
4614d5ac70f0Sopenharmony_ci	seq->ibuflen = 0;
4615d5ac70f0Sopenharmony_ci	return 0;
4616d5ac70f0Sopenharmony_ci}
4617d5ac70f0Sopenharmony_ci
4618d5ac70f0Sopenharmony_ci/**
4619d5ac70f0Sopenharmony_ci * \brief remove all events on output buffer
4620d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4621d5ac70f0Sopenharmony_ci *
4622d5ac70f0Sopenharmony_ci * Removes all events on both user-space output buffer and
4623d5ac70f0Sopenharmony_ci * output memory pool on kernel.
4624d5ac70f0Sopenharmony_ci *
4625d5ac70f0Sopenharmony_ci * \sa snd_seq_drain_output(), snd_seq_drop_output_buffer(), snd_seq_remove_events()
4626d5ac70f0Sopenharmony_ci */
4627d5ac70f0Sopenharmony_ciint snd_seq_drop_output(snd_seq_t *seq)
4628d5ac70f0Sopenharmony_ci{
4629d5ac70f0Sopenharmony_ci	snd_seq_remove_events_t rminfo;
4630d5ac70f0Sopenharmony_ci	assert(seq);
4631d5ac70f0Sopenharmony_ci
4632d5ac70f0Sopenharmony_ci	memset(&rminfo, 0, sizeof(rminfo));
4633d5ac70f0Sopenharmony_ci	rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;
4634d5ac70f0Sopenharmony_ci
4635d5ac70f0Sopenharmony_ci	return snd_seq_remove_events(seq, &rminfo);
4636d5ac70f0Sopenharmony_ci}
4637d5ac70f0Sopenharmony_ci
4638d5ac70f0Sopenharmony_ci/**
4639d5ac70f0Sopenharmony_ci * \brief clear input buffer and and remove events in sequencer queue
4640d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4641d5ac70f0Sopenharmony_ci *
4642d5ac70f0Sopenharmony_ci * \sa snd_seq_drop_input_buffer(), snd_seq_remove_events()
4643d5ac70f0Sopenharmony_ci */
4644d5ac70f0Sopenharmony_ciint snd_seq_drop_input(snd_seq_t *seq)
4645d5ac70f0Sopenharmony_ci{
4646d5ac70f0Sopenharmony_ci	snd_seq_remove_events_t rminfo;
4647d5ac70f0Sopenharmony_ci	assert(seq);
4648d5ac70f0Sopenharmony_ci
4649d5ac70f0Sopenharmony_ci	memset(&rminfo, 0, sizeof(rminfo));
4650d5ac70f0Sopenharmony_ci	rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;
4651d5ac70f0Sopenharmony_ci
4652d5ac70f0Sopenharmony_ci	return snd_seq_remove_events(seq, &rminfo);
4653d5ac70f0Sopenharmony_ci}
4654d5ac70f0Sopenharmony_ci
4655d5ac70f0Sopenharmony_ci
4656d5ac70f0Sopenharmony_ci/**
4657d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_remove_events_t
4658d5ac70f0Sopenharmony_ci * \return size in bytes
4659d5ac70f0Sopenharmony_ci */
4660d5ac70f0Sopenharmony_cisize_t snd_seq_remove_events_sizeof()
4661d5ac70f0Sopenharmony_ci{
4662d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_remove_events_t);
4663d5ac70f0Sopenharmony_ci}
4664d5ac70f0Sopenharmony_ci
4665d5ac70f0Sopenharmony_ci/**
4666d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
4667d5ac70f0Sopenharmony_ci * \param ptr returned pointer
4668d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
4669d5ac70f0Sopenharmony_ci */
4670d5ac70f0Sopenharmony_ciint snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
4671d5ac70f0Sopenharmony_ci{
4672d5ac70f0Sopenharmony_ci	assert(ptr);
4673d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_remove_events_t));
4674d5ac70f0Sopenharmony_ci	if (!*ptr)
4675d5ac70f0Sopenharmony_ci		return -ENOMEM;
4676d5ac70f0Sopenharmony_ci	return 0;
4677d5ac70f0Sopenharmony_ci}
4678d5ac70f0Sopenharmony_ci
4679d5ac70f0Sopenharmony_ci/**
4680d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_remove_events_t
4681d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
4682d5ac70f0Sopenharmony_ci */
4683d5ac70f0Sopenharmony_civoid snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
4684d5ac70f0Sopenharmony_ci{
4685d5ac70f0Sopenharmony_ci	free(obj);
4686d5ac70f0Sopenharmony_ci}
4687d5ac70f0Sopenharmony_ci
4688d5ac70f0Sopenharmony_ci/**
4689d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_remove_events_t to another
4690d5ac70f0Sopenharmony_ci * \param dst pointer to destination
4691d5ac70f0Sopenharmony_ci * \param src pointer to source
4692d5ac70f0Sopenharmony_ci */
4693d5ac70f0Sopenharmony_civoid snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
4694d5ac70f0Sopenharmony_ci{
4695d5ac70f0Sopenharmony_ci	assert(dst && src);
4696d5ac70f0Sopenharmony_ci	*dst = *src;
4697d5ac70f0Sopenharmony_ci}
4698d5ac70f0Sopenharmony_ci
4699d5ac70f0Sopenharmony_ci
4700d5ac70f0Sopenharmony_ci/**
4701d5ac70f0Sopenharmony_ci * \brief Get the removal condition bits
4702d5ac70f0Sopenharmony_ci * \param info remove_events container
4703d5ac70f0Sopenharmony_ci * \return removal condition bits
4704d5ac70f0Sopenharmony_ci *
4705d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4706d5ac70f0Sopenharmony_ci */
4707d5ac70f0Sopenharmony_ciunsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
4708d5ac70f0Sopenharmony_ci{
4709d5ac70f0Sopenharmony_ci	assert(info);
4710d5ac70f0Sopenharmony_ci	return info->remove_mode;
4711d5ac70f0Sopenharmony_ci}
4712d5ac70f0Sopenharmony_ci
4713d5ac70f0Sopenharmony_ci/**
4714d5ac70f0Sopenharmony_ci * \brief Get the queue as removal condition
4715d5ac70f0Sopenharmony_ci * \param info remove_events container
4716d5ac70f0Sopenharmony_ci * \return queue id
4717d5ac70f0Sopenharmony_ci *
4718d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4719d5ac70f0Sopenharmony_ci */
4720d5ac70f0Sopenharmony_ciint snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
4721d5ac70f0Sopenharmony_ci{
4722d5ac70f0Sopenharmony_ci	assert(info);
4723d5ac70f0Sopenharmony_ci	return info->queue;
4724d5ac70f0Sopenharmony_ci}
4725d5ac70f0Sopenharmony_ci
4726d5ac70f0Sopenharmony_ci/**
4727d5ac70f0Sopenharmony_ci * \brief Get the event timestamp as removal condition
4728d5ac70f0Sopenharmony_ci * \param info remove_events container
4729d5ac70f0Sopenharmony_ci * \return time stamp
4730d5ac70f0Sopenharmony_ci *
4731d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4732d5ac70f0Sopenharmony_ci */
4733d5ac70f0Sopenharmony_ciconst snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
4734d5ac70f0Sopenharmony_ci{
4735d5ac70f0Sopenharmony_ci	assert(info);
4736d5ac70f0Sopenharmony_ci	return (const snd_seq_timestamp_t *)&info->time;
4737d5ac70f0Sopenharmony_ci}
4738d5ac70f0Sopenharmony_ci
4739d5ac70f0Sopenharmony_ci/**
4740d5ac70f0Sopenharmony_ci * \brief Get the event destination address as removal condition
4741d5ac70f0Sopenharmony_ci * \param info remove_events container
4742d5ac70f0Sopenharmony_ci * \return destination address
4743d5ac70f0Sopenharmony_ci *
4744d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4745d5ac70f0Sopenharmony_ci */
4746d5ac70f0Sopenharmony_ciconst snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
4747d5ac70f0Sopenharmony_ci{
4748d5ac70f0Sopenharmony_ci	assert(info);
4749d5ac70f0Sopenharmony_ci	return (const snd_seq_addr_t *)&info->dest;
4750d5ac70f0Sopenharmony_ci}
4751d5ac70f0Sopenharmony_ci
4752d5ac70f0Sopenharmony_ci/**
4753d5ac70f0Sopenharmony_ci * \brief Get the event channel as removal condition
4754d5ac70f0Sopenharmony_ci * \param info remove_events container
4755d5ac70f0Sopenharmony_ci * \return channel number
4756d5ac70f0Sopenharmony_ci *
4757d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4758d5ac70f0Sopenharmony_ci */
4759d5ac70f0Sopenharmony_ciint snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
4760d5ac70f0Sopenharmony_ci{
4761d5ac70f0Sopenharmony_ci	assert(info);
4762d5ac70f0Sopenharmony_ci	return info->channel;
4763d5ac70f0Sopenharmony_ci}
4764d5ac70f0Sopenharmony_ci
4765d5ac70f0Sopenharmony_ci/**
4766d5ac70f0Sopenharmony_ci * \brief Get the event type as removal condition
4767d5ac70f0Sopenharmony_ci * \param info remove_events container
4768d5ac70f0Sopenharmony_ci * \return event type
4769d5ac70f0Sopenharmony_ci *
4770d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4771d5ac70f0Sopenharmony_ci */
4772d5ac70f0Sopenharmony_ciint snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
4773d5ac70f0Sopenharmony_ci{
4774d5ac70f0Sopenharmony_ci	assert(info);
4775d5ac70f0Sopenharmony_ci	return info->type;
4776d5ac70f0Sopenharmony_ci}
4777d5ac70f0Sopenharmony_ci
4778d5ac70f0Sopenharmony_ci/**
4779d5ac70f0Sopenharmony_ci * \brief Get the event tag id as removal condition
4780d5ac70f0Sopenharmony_ci * \param info remove_events container
4781d5ac70f0Sopenharmony_ci * \return tag id
4782d5ac70f0Sopenharmony_ci *
4783d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4784d5ac70f0Sopenharmony_ci */
4785d5ac70f0Sopenharmony_ciint snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
4786d5ac70f0Sopenharmony_ci{
4787d5ac70f0Sopenharmony_ci	assert(info);
4788d5ac70f0Sopenharmony_ci	return info->tag;
4789d5ac70f0Sopenharmony_ci}
4790d5ac70f0Sopenharmony_ci
4791d5ac70f0Sopenharmony_ci/**
4792d5ac70f0Sopenharmony_ci * \brief Set the removal condition bits
4793d5ac70f0Sopenharmony_ci * \param info remove_events container
4794d5ac70f0Sopenharmony_ci * \param flags removal condition bits
4795d5ac70f0Sopenharmony_ci *
4796d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4797d5ac70f0Sopenharmony_ci */
4798d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
4799d5ac70f0Sopenharmony_ci{
4800d5ac70f0Sopenharmony_ci	assert(info);
4801d5ac70f0Sopenharmony_ci	info->remove_mode = flags;
4802d5ac70f0Sopenharmony_ci}
4803d5ac70f0Sopenharmony_ci
4804d5ac70f0Sopenharmony_ci/**
4805d5ac70f0Sopenharmony_ci * \brief Set the queue as removal condition
4806d5ac70f0Sopenharmony_ci * \param info remove_events container
4807d5ac70f0Sopenharmony_ci * \param queue queue id
4808d5ac70f0Sopenharmony_ci *
4809d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4810d5ac70f0Sopenharmony_ci */
4811d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
4812d5ac70f0Sopenharmony_ci{
4813d5ac70f0Sopenharmony_ci	assert(info);
4814d5ac70f0Sopenharmony_ci	info->queue = queue;
4815d5ac70f0Sopenharmony_ci}
4816d5ac70f0Sopenharmony_ci
4817d5ac70f0Sopenharmony_ci/**
4818d5ac70f0Sopenharmony_ci * \brief Set the timestamp as removal condition
4819d5ac70f0Sopenharmony_ci * \param info remove_events container
4820d5ac70f0Sopenharmony_ci * \param time timestamp pointer
4821d5ac70f0Sopenharmony_ci *
4822d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4823d5ac70f0Sopenharmony_ci */
4824d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
4825d5ac70f0Sopenharmony_ci{
4826d5ac70f0Sopenharmony_ci	assert(info);
4827d5ac70f0Sopenharmony_ci	info->time = *(const union sndrv_seq_timestamp *)time;
4828d5ac70f0Sopenharmony_ci}
4829d5ac70f0Sopenharmony_ci
4830d5ac70f0Sopenharmony_ci/**
4831d5ac70f0Sopenharmony_ci * \brief Set the destination address as removal condition
4832d5ac70f0Sopenharmony_ci * \param info remove_events container
4833d5ac70f0Sopenharmony_ci * \param addr destination address
4834d5ac70f0Sopenharmony_ci *
4835d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4836d5ac70f0Sopenharmony_ci */
4837d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
4838d5ac70f0Sopenharmony_ci{
4839d5ac70f0Sopenharmony_ci	assert(info);
4840d5ac70f0Sopenharmony_ci	info->dest = *(const struct sndrv_seq_addr *)addr;
4841d5ac70f0Sopenharmony_ci}
4842d5ac70f0Sopenharmony_ci
4843d5ac70f0Sopenharmony_ci/**
4844d5ac70f0Sopenharmony_ci * \brief Set the channel as removal condition
4845d5ac70f0Sopenharmony_ci * \param info remove_events container
4846d5ac70f0Sopenharmony_ci * \param channel channel number
4847d5ac70f0Sopenharmony_ci *
4848d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4849d5ac70f0Sopenharmony_ci */
4850d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
4851d5ac70f0Sopenharmony_ci{
4852d5ac70f0Sopenharmony_ci	assert(info);
4853d5ac70f0Sopenharmony_ci	info->channel = channel;
4854d5ac70f0Sopenharmony_ci}
4855d5ac70f0Sopenharmony_ci
4856d5ac70f0Sopenharmony_ci/**
4857d5ac70f0Sopenharmony_ci * \brief Set the event type as removal condition
4858d5ac70f0Sopenharmony_ci * \param info remove_events container
4859d5ac70f0Sopenharmony_ci * \param type event type
4860d5ac70f0Sopenharmony_ci *
4861d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4862d5ac70f0Sopenharmony_ci */
4863d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
4864d5ac70f0Sopenharmony_ci{
4865d5ac70f0Sopenharmony_ci	assert(info);
4866d5ac70f0Sopenharmony_ci	info->type = type;
4867d5ac70f0Sopenharmony_ci}
4868d5ac70f0Sopenharmony_ci
4869d5ac70f0Sopenharmony_ci/**
4870d5ac70f0Sopenharmony_ci * \brief Set the event tag as removal condition
4871d5ac70f0Sopenharmony_ci * \param info remove_events container
4872d5ac70f0Sopenharmony_ci * \param tag tag id
4873d5ac70f0Sopenharmony_ci *
4874d5ac70f0Sopenharmony_ci * \sa snd_seq_remove_events()
4875d5ac70f0Sopenharmony_ci */
4876d5ac70f0Sopenharmony_civoid snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
4877d5ac70f0Sopenharmony_ci{
4878d5ac70f0Sopenharmony_ci	assert(info);
4879d5ac70f0Sopenharmony_ci	info->tag = tag;
4880d5ac70f0Sopenharmony_ci}
4881d5ac70f0Sopenharmony_ci
4882d5ac70f0Sopenharmony_ci
4883d5ac70f0Sopenharmony_ci/* compare timestamp between events */
4884d5ac70f0Sopenharmony_ci/* return 1 if a >= b; otherwise return 0 */
4885d5ac70f0Sopenharmony_cistatic inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
4886d5ac70f0Sopenharmony_ci{
4887d5ac70f0Sopenharmony_ci	/* compare ticks */
4888d5ac70f0Sopenharmony_ci	return (*a >= *b);
4889d5ac70f0Sopenharmony_ci}
4890d5ac70f0Sopenharmony_ci
4891d5ac70f0Sopenharmony_cistatic inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
4892d5ac70f0Sopenharmony_ci{
4893d5ac70f0Sopenharmony_ci	/* compare real time */
4894d5ac70f0Sopenharmony_ci	if (a->tv_sec > b->tv_sec)
4895d5ac70f0Sopenharmony_ci		return 1;
4896d5ac70f0Sopenharmony_ci	if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
4897d5ac70f0Sopenharmony_ci		return 1;
4898d5ac70f0Sopenharmony_ci	return 0;
4899d5ac70f0Sopenharmony_ci}
4900d5ac70f0Sopenharmony_ci
4901d5ac70f0Sopenharmony_ci/* Routine to match events to be removed */
4902d5ac70f0Sopenharmony_cistatic int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
4903d5ac70f0Sopenharmony_ci{
4904d5ac70f0Sopenharmony_ci	int res;
4905d5ac70f0Sopenharmony_ci
4906d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
4907d5ac70f0Sopenharmony_ci		if (ev->dest.client != info->dest.client ||
4908d5ac70f0Sopenharmony_ci				ev->dest.port != info->dest.port)
4909d5ac70f0Sopenharmony_ci			return 0;
4910d5ac70f0Sopenharmony_ci	}
4911d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
4912d5ac70f0Sopenharmony_ci		if (! snd_seq_ev_is_channel_type(ev))
4913d5ac70f0Sopenharmony_ci			return 0;
4914d5ac70f0Sopenharmony_ci		/* data.note.channel and data.control.channel are identical */
4915d5ac70f0Sopenharmony_ci		if (ev->data.note.channel != info->channel)
4916d5ac70f0Sopenharmony_ci			return 0;
4917d5ac70f0Sopenharmony_ci	}
4918d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
4919d5ac70f0Sopenharmony_ci		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4920d5ac70f0Sopenharmony_ci			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4921d5ac70f0Sopenharmony_ci		else
4922d5ac70f0Sopenharmony_ci			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4923d5ac70f0Sopenharmony_ci		if (!res)
4924d5ac70f0Sopenharmony_ci			return 0;
4925d5ac70f0Sopenharmony_ci	}
4926d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
4927d5ac70f0Sopenharmony_ci		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4928d5ac70f0Sopenharmony_ci			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4929d5ac70f0Sopenharmony_ci		else
4930d5ac70f0Sopenharmony_ci			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4931d5ac70f0Sopenharmony_ci		if (res)
4932d5ac70f0Sopenharmony_ci			return 0;
4933d5ac70f0Sopenharmony_ci	}
4934d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
4935d5ac70f0Sopenharmony_ci		if (ev->type != info->type)
4936d5ac70f0Sopenharmony_ci			return 0;
4937d5ac70f0Sopenharmony_ci	}
4938d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
4939d5ac70f0Sopenharmony_ci		/* Do not remove off events */
4940d5ac70f0Sopenharmony_ci		switch (ev->type) {
4941d5ac70f0Sopenharmony_ci		case SND_SEQ_EVENT_NOTEOFF:
4942d5ac70f0Sopenharmony_ci		/* case SND_SEQ_EVENT_SAMPLE_STOP: */
4943d5ac70f0Sopenharmony_ci			return 0;
4944d5ac70f0Sopenharmony_ci		default:
4945d5ac70f0Sopenharmony_ci			break;
4946d5ac70f0Sopenharmony_ci		}
4947d5ac70f0Sopenharmony_ci	}
4948d5ac70f0Sopenharmony_ci	if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
4949d5ac70f0Sopenharmony_ci		if (info->tag != ev->tag)
4950d5ac70f0Sopenharmony_ci			return 0;
4951d5ac70f0Sopenharmony_ci	}
4952d5ac70f0Sopenharmony_ci
4953d5ac70f0Sopenharmony_ci	return 1;
4954d5ac70f0Sopenharmony_ci}
4955d5ac70f0Sopenharmony_ci
4956d5ac70f0Sopenharmony_ci/**
4957d5ac70f0Sopenharmony_ci * \brief remove events on input/output buffers and pools
4958d5ac70f0Sopenharmony_ci * \param seq sequencer handle
4959d5ac70f0Sopenharmony_ci * \param rmp remove event container
4960d5ac70f0Sopenharmony_ci *
4961d5ac70f0Sopenharmony_ci * Removes matching events with the given condition from input/output buffers
4962d5ac70f0Sopenharmony_ci * and pools.
4963d5ac70f0Sopenharmony_ci * The removal condition is specified in \a rmp argument.
4964d5ac70f0Sopenharmony_ci *
4965d5ac70f0Sopenharmony_ci * \sa snd_seq_event_output(), snd_seq_drop_output(), snd_seq_reset_pool_output()
4966d5ac70f0Sopenharmony_ci */
4967d5ac70f0Sopenharmony_ciint snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
4968d5ac70f0Sopenharmony_ci{
4969d5ac70f0Sopenharmony_ci	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
4970d5ac70f0Sopenharmony_ci		/*
4971d5ac70f0Sopenharmony_ci		 * First deal with any events that are still buffered
4972d5ac70f0Sopenharmony_ci		 * in the library.
4973d5ac70f0Sopenharmony_ci		 */
4974d5ac70f0Sopenharmony_ci		snd_seq_drop_input_buffer(seq);
4975d5ac70f0Sopenharmony_ci	}
4976d5ac70f0Sopenharmony_ci
4977d5ac70f0Sopenharmony_ci	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
4978d5ac70f0Sopenharmony_ci		/*
4979d5ac70f0Sopenharmony_ci		 * First deal with any events that are still buffered
4980d5ac70f0Sopenharmony_ci		 * in the library.
4981d5ac70f0Sopenharmony_ci		 */
4982d5ac70f0Sopenharmony_ci		 if (! (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT))) {
4983d5ac70f0Sopenharmony_ci			 /* The simple case - remove all */
4984d5ac70f0Sopenharmony_ci			 snd_seq_drop_output_buffer(seq);
4985d5ac70f0Sopenharmony_ci		} else {
4986d5ac70f0Sopenharmony_ci			char *ep;
4987d5ac70f0Sopenharmony_ci			size_t len;
4988d5ac70f0Sopenharmony_ci			snd_seq_event_t *ev;
4989d5ac70f0Sopenharmony_ci
4990d5ac70f0Sopenharmony_ci			ep = seq->obuf;
4991d5ac70f0Sopenharmony_ci			while (ep - seq->obuf < (ssize_t)seq->obufused) {
4992d5ac70f0Sopenharmony_ci
4993d5ac70f0Sopenharmony_ci				ev = (snd_seq_event_t *)ep;
4994d5ac70f0Sopenharmony_ci				len = snd_seq_event_length(ev);
4995d5ac70f0Sopenharmony_ci
4996d5ac70f0Sopenharmony_ci				if (remove_match(rmp, ev)) {
4997d5ac70f0Sopenharmony_ci					/* Remove event */
4998d5ac70f0Sopenharmony_ci					seq->obufused -= len;
4999d5ac70f0Sopenharmony_ci					memmove(ep, ep + len, seq->obufused - (ep - seq->obuf));
5000d5ac70f0Sopenharmony_ci				} else {
5001d5ac70f0Sopenharmony_ci					ep += len;
5002d5ac70f0Sopenharmony_ci				}
5003d5ac70f0Sopenharmony_ci			}
5004d5ac70f0Sopenharmony_ci		}
5005d5ac70f0Sopenharmony_ci	}
5006d5ac70f0Sopenharmony_ci
5007d5ac70f0Sopenharmony_ci	return seq->ops->remove_events(seq, rmp);
5008d5ac70f0Sopenharmony_ci}
5009d5ac70f0Sopenharmony_ci
5010d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
5011d5ac70f0Sopenharmony_ci
5012d5ac70f0Sopenharmony_ci/*
5013d5ac70f0Sopenharmony_ci * client memory pool
5014d5ac70f0Sopenharmony_ci */
5015d5ac70f0Sopenharmony_ci
5016d5ac70f0Sopenharmony_ci/**
5017d5ac70f0Sopenharmony_ci * \brief get size of #snd_seq_client_pool_t
5018d5ac70f0Sopenharmony_ci * \return size in bytes
5019d5ac70f0Sopenharmony_ci */
5020d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_sizeof()
5021d5ac70f0Sopenharmony_ci{
5022d5ac70f0Sopenharmony_ci	return sizeof(snd_seq_client_pool_t);
5023d5ac70f0Sopenharmony_ci}
5024d5ac70f0Sopenharmony_ci
5025d5ac70f0Sopenharmony_ci/**
5026d5ac70f0Sopenharmony_ci * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
5027d5ac70f0Sopenharmony_ci * \param ptr returned pointer
5028d5ac70f0Sopenharmony_ci * \return 0 on success otherwise negative error code
5029d5ac70f0Sopenharmony_ci */
5030d5ac70f0Sopenharmony_ciint snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
5031d5ac70f0Sopenharmony_ci{
5032d5ac70f0Sopenharmony_ci	assert(ptr);
5033d5ac70f0Sopenharmony_ci	*ptr = calloc(1, sizeof(snd_seq_client_pool_t));
5034d5ac70f0Sopenharmony_ci	if (!*ptr)
5035d5ac70f0Sopenharmony_ci		return -ENOMEM;
5036d5ac70f0Sopenharmony_ci	return 0;
5037d5ac70f0Sopenharmony_ci}
5038d5ac70f0Sopenharmony_ci
5039d5ac70f0Sopenharmony_ci/**
5040d5ac70f0Sopenharmony_ci * \brief frees a previously allocated #snd_seq_client_pool_t
5041d5ac70f0Sopenharmony_ci * \param obj pointer to object to free
5042d5ac70f0Sopenharmony_ci */
5043d5ac70f0Sopenharmony_civoid snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
5044d5ac70f0Sopenharmony_ci{
5045d5ac70f0Sopenharmony_ci	free(obj);
5046d5ac70f0Sopenharmony_ci}
5047d5ac70f0Sopenharmony_ci
5048d5ac70f0Sopenharmony_ci/**
5049d5ac70f0Sopenharmony_ci * \brief copy one #snd_seq_client_pool_t to another
5050d5ac70f0Sopenharmony_ci * \param dst pointer to destination
5051d5ac70f0Sopenharmony_ci * \param src pointer to source
5052d5ac70f0Sopenharmony_ci */
5053d5ac70f0Sopenharmony_civoid snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
5054d5ac70f0Sopenharmony_ci{
5055d5ac70f0Sopenharmony_ci	assert(dst && src);
5056d5ac70f0Sopenharmony_ci	*dst = *src;
5057d5ac70f0Sopenharmony_ci}
5058d5ac70f0Sopenharmony_ci
5059d5ac70f0Sopenharmony_ci
5060d5ac70f0Sopenharmony_ci/**
5061d5ac70f0Sopenharmony_ci * \brief Get the client id of a queue_info container
5062d5ac70f0Sopenharmony_ci * \param info client_pool container
5063d5ac70f0Sopenharmony_ci * \return client id
5064d5ac70f0Sopenharmony_ci */
5065d5ac70f0Sopenharmony_ciint snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
5066d5ac70f0Sopenharmony_ci{
5067d5ac70f0Sopenharmony_ci	assert(info);
5068d5ac70f0Sopenharmony_ci	return info->client;
5069d5ac70f0Sopenharmony_ci}
5070d5ac70f0Sopenharmony_ci
5071d5ac70f0Sopenharmony_ci/**
5072d5ac70f0Sopenharmony_ci * \brief Get the output pool size of a queue_info container
5073d5ac70f0Sopenharmony_ci * \param info client_pool container
5074d5ac70f0Sopenharmony_ci * \return output pool size
5075d5ac70f0Sopenharmony_ci */
5076d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
5077d5ac70f0Sopenharmony_ci{
5078d5ac70f0Sopenharmony_ci	assert(info);
5079d5ac70f0Sopenharmony_ci	return info->output_pool;
5080d5ac70f0Sopenharmony_ci}
5081d5ac70f0Sopenharmony_ci
5082d5ac70f0Sopenharmony_ci/**
5083d5ac70f0Sopenharmony_ci * \brief Get the input pool size of a queue_info container
5084d5ac70f0Sopenharmony_ci * \param info client_pool container
5085d5ac70f0Sopenharmony_ci * \return input pool size
5086d5ac70f0Sopenharmony_ci */
5087d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
5088d5ac70f0Sopenharmony_ci{
5089d5ac70f0Sopenharmony_ci	assert(info);
5090d5ac70f0Sopenharmony_ci	return info->input_pool;
5091d5ac70f0Sopenharmony_ci}
5092d5ac70f0Sopenharmony_ci
5093d5ac70f0Sopenharmony_ci/**
5094d5ac70f0Sopenharmony_ci * \brief Get the output room size of a queue_info container
5095d5ac70f0Sopenharmony_ci * \param info client_pool container
5096d5ac70f0Sopenharmony_ci * \return output room size
5097d5ac70f0Sopenharmony_ci */
5098d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
5099d5ac70f0Sopenharmony_ci{
5100d5ac70f0Sopenharmony_ci	assert(info);
5101d5ac70f0Sopenharmony_ci	return info->output_room;
5102d5ac70f0Sopenharmony_ci}
5103d5ac70f0Sopenharmony_ci
5104d5ac70f0Sopenharmony_ci/**
5105d5ac70f0Sopenharmony_ci * \brief Get the available size on output pool of a queue_info container
5106d5ac70f0Sopenharmony_ci * \param info client_pool container
5107d5ac70f0Sopenharmony_ci * \return available output size
5108d5ac70f0Sopenharmony_ci */
5109d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
5110d5ac70f0Sopenharmony_ci{
5111d5ac70f0Sopenharmony_ci	assert(info);
5112d5ac70f0Sopenharmony_ci	return info->output_free;
5113d5ac70f0Sopenharmony_ci}
5114d5ac70f0Sopenharmony_ci
5115d5ac70f0Sopenharmony_ci/**
5116d5ac70f0Sopenharmony_ci * \brief Get the available size on input pool of a queue_info container
5117d5ac70f0Sopenharmony_ci * \param info client_pool container
5118d5ac70f0Sopenharmony_ci * \return available input size
5119d5ac70f0Sopenharmony_ci */
5120d5ac70f0Sopenharmony_cisize_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
5121d5ac70f0Sopenharmony_ci{
5122d5ac70f0Sopenharmony_ci	assert(info);
5123d5ac70f0Sopenharmony_ci	return info->input_free;
5124d5ac70f0Sopenharmony_ci}
5125d5ac70f0Sopenharmony_ci
5126d5ac70f0Sopenharmony_ci/**
5127d5ac70f0Sopenharmony_ci * \brief Set the output pool size of a queue_info container
5128d5ac70f0Sopenharmony_ci * \param info client_pool container
5129d5ac70f0Sopenharmony_ci * \param size output pool size
5130d5ac70f0Sopenharmony_ci */
5131d5ac70f0Sopenharmony_civoid snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
5132d5ac70f0Sopenharmony_ci{
5133d5ac70f0Sopenharmony_ci	assert(info);
5134d5ac70f0Sopenharmony_ci	info->output_pool = size;
5135d5ac70f0Sopenharmony_ci}
5136d5ac70f0Sopenharmony_ci
5137d5ac70f0Sopenharmony_ci/**
5138d5ac70f0Sopenharmony_ci * \brief Set the input pool size of a queue_info container
5139d5ac70f0Sopenharmony_ci * \param info client_pool container
5140d5ac70f0Sopenharmony_ci * \param size input pool size
5141d5ac70f0Sopenharmony_ci */
5142d5ac70f0Sopenharmony_civoid snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
5143d5ac70f0Sopenharmony_ci{
5144d5ac70f0Sopenharmony_ci	assert(info);
5145d5ac70f0Sopenharmony_ci	info->input_pool = size;
5146d5ac70f0Sopenharmony_ci}
5147d5ac70f0Sopenharmony_ci
5148d5ac70f0Sopenharmony_ci/**
5149d5ac70f0Sopenharmony_ci * \brief Set the output room size of a queue_info container
5150d5ac70f0Sopenharmony_ci * \param info client_pool container
5151d5ac70f0Sopenharmony_ci * \param size output room size
5152d5ac70f0Sopenharmony_ci */
5153d5ac70f0Sopenharmony_civoid snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
5154d5ac70f0Sopenharmony_ci{
5155d5ac70f0Sopenharmony_ci	assert(info);
5156d5ac70f0Sopenharmony_ci	info->output_room = size;
5157d5ac70f0Sopenharmony_ci}
5158d5ac70f0Sopenharmony_ci
5159d5ac70f0Sopenharmony_ci
5160d5ac70f0Sopenharmony_ci/**
5161d5ac70f0Sopenharmony_ci * \brief obtain the pool information of the current client
5162d5ac70f0Sopenharmony_ci * \param seq sequencer handle
5163d5ac70f0Sopenharmony_ci * \param info information to be stored
5164d5ac70f0Sopenharmony_ci */
5165d5ac70f0Sopenharmony_ciint snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
5166d5ac70f0Sopenharmony_ci{
5167d5ac70f0Sopenharmony_ci	assert(seq && info);
5168d5ac70f0Sopenharmony_ci	info->client = seq->client;
5169d5ac70f0Sopenharmony_ci	return seq->ops->get_client_pool(seq, info);
5170d5ac70f0Sopenharmony_ci}
5171d5ac70f0Sopenharmony_ci
5172d5ac70f0Sopenharmony_ci/**
5173d5ac70f0Sopenharmony_ci * \brief set the pool information
5174d5ac70f0Sopenharmony_ci * \param seq sequencer handle
5175d5ac70f0Sopenharmony_ci * \param info information to update
5176d5ac70f0Sopenharmony_ci *
5177d5ac70f0Sopenharmony_ci * Sets the pool information of the current client.
5178d5ac70f0Sopenharmony_ci * The client field in \a info is replaced automatically with the current id.
5179d5ac70f0Sopenharmony_ci */
5180d5ac70f0Sopenharmony_ciint snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
5181d5ac70f0Sopenharmony_ci{
5182d5ac70f0Sopenharmony_ci	assert(seq && info);
5183d5ac70f0Sopenharmony_ci	info->client = seq->client;
5184d5ac70f0Sopenharmony_ci	return seq->ops->set_client_pool(seq, info);
5185d5ac70f0Sopenharmony_ci}
5186d5ac70f0Sopenharmony_ci
5187d5ac70f0Sopenharmony_ci/*----------------------------------------------------------------*/
5188d5ac70f0Sopenharmony_ci
5189d5ac70f0Sopenharmony_ci/*
5190d5ac70f0Sopenharmony_ci * misc.
5191d5ac70f0Sopenharmony_ci */
5192d5ac70f0Sopenharmony_ci
5193d5ac70f0Sopenharmony_ci/**
5194d5ac70f0Sopenharmony_ci * \brief set a bit flag
5195d5ac70f0Sopenharmony_ci */
5196d5ac70f0Sopenharmony_civoid snd_seq_set_bit(int nr, void *array)
5197d5ac70f0Sopenharmony_ci{
5198d5ac70f0Sopenharmony_ci	((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
5199d5ac70f0Sopenharmony_ci}
5200d5ac70f0Sopenharmony_ci
5201d5ac70f0Sopenharmony_ci/**
5202d5ac70f0Sopenharmony_ci * \brief unset a bit flag
5203d5ac70f0Sopenharmony_ci */
5204d5ac70f0Sopenharmony_civoid snd_seq_unset_bit(int nr, void *array)
5205d5ac70f0Sopenharmony_ci{
5206d5ac70f0Sopenharmony_ci       ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
5207d5ac70f0Sopenharmony_ci}
5208d5ac70f0Sopenharmony_ci
5209d5ac70f0Sopenharmony_ci/**
5210d5ac70f0Sopenharmony_ci * \brief change a bit flag
5211d5ac70f0Sopenharmony_ci */
5212d5ac70f0Sopenharmony_ciint snd_seq_change_bit(int nr, void *array)
5213d5ac70f0Sopenharmony_ci{
5214d5ac70f0Sopenharmony_ci	int result;
5215d5ac70f0Sopenharmony_ci
5216d5ac70f0Sopenharmony_ci	result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
5217d5ac70f0Sopenharmony_ci	((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
5218d5ac70f0Sopenharmony_ci	return result;
5219d5ac70f0Sopenharmony_ci}
5220d5ac70f0Sopenharmony_ci
5221d5ac70f0Sopenharmony_ci/**
5222d5ac70f0Sopenharmony_ci * \brief get a bit flag state
5223d5ac70f0Sopenharmony_ci */
5224d5ac70f0Sopenharmony_ciint snd_seq_get_bit(int nr, void *array)
5225d5ac70f0Sopenharmony_ci{
5226d5ac70f0Sopenharmony_ci	return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
5227d5ac70f0Sopenharmony_ci}
5228