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