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