1/** 2 * \file rawmidi/rawmidi.c 3 * \brief RawMidi Interface 4 * \author Jaroslav Kysela <perex@perex.cz> 5 * \author Abramo Bagnara <abramo@alsa-project.org> 6 * \date 2000-2001 7 * 8 * See the \ref rawmidi page for more details. 9 */ 10/* 11 * 12 * This library is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU Lesser General Public License as 14 * published by the Free Software Foundation; either version 2.1 of 15 * the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Lesser General Public License for more details. 21 * 22 * You should have received a copy of the GNU Lesser General Public 23 * License along with this library; if not, write to the Free Software 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 25 * 26 */ 27 28/*! \page rawmidi RawMidi interface 29 30<P>RawMidi Interface is designed to write or read raw (unchanged) MIDI 31data over the MIDI line without any timestamps defined in interface. MIDI 32stands Musical Instrument Digital Interface and more information about 33this standard can be found at http://www.midi.org. 34 35\section rawmidi_general_overview General overview 36 37The rawmidi implementation uses ring buffers to store outgoing and incoming 38MIDI stream. The buffer size is tunable and drivers report underruns for incoming 39stream as well. 40 41\section rawmidi_open Open handling 42 43RawMidi devices are opened exclusively for a selected direction. 44While more than one process may not open a given MIDI device in the same 45direction simultaneously, separate processes may open a single MIDI device 46in different directions (i.e. process one opens a MIDI device in write 47direction and process two opens the same device in read direction). 48 49\subsection rawmidi_open_nonblock Nonblocking open (flag) 50 51Using #SND_RAWMIDI_NONBLOCK flag for snd_rawmidi_open() or snd_rawmidi_open_lconf() 52instruct device driver to return the -EBUSY error when device is already occupied 53with another application. This flag also changes behaviour of snd_rawmidi_write() 54and snd_rawmidi_read() returning -EAGAIN when no more bytes can be processed. 55 56Note: In opposite (default) behaviour, application is blocked until device resources 57are free. 58 59\subsection rawmidi_open_append Append open (flag) 60 61Using #SND_RAWMIDI_APPEND flag (output only) instruct device driver to append 62contents of written buffer - passed by snd_rawmidi_write() - atomically 63to output ring buffer in the kernel space. This flag also means that device 64is not opened exclusively, so more applications can share given rawmidi device. 65Note that applications must send the whole MIDI message including the running status, 66because another writing application might break the MIDI message in the output 67buffer. 68 69\subsection rawmidi_open_sync Sync open (flag) 70 71Using #SND_RAWMIDI_SYNC flag (output only) assures that the contents of output 72buffer specified using snd_rawmidi_write() is always drained before the function 73exits. This behaviour is same like 'snd_rawmidi_write() followed by 74snd_rawmidi_drain() immediately'. 75 76\subsection rawmidi_io I/O handling 77 78There is only standard read/write access to device internal ring buffer. Use 79snd_rawmidi_read() and snd_rawmidi_write() functions to obtain / write MIDI bytes. 80 81\subsection rawmidi_dev_names RawMidi naming conventions 82 83The ALSA library uses a generic string representation for names of devices. 84The devices might be virtual, physical or a mix of both. The generic string 85is passed to \link ::snd_rawmidi_open() \endlink or \link ::snd_rawmidi_open_lconf() \endlink. 86It contains two parts: device name and arguments. Devices and arguments are described 87in configuration files. The usual place for default definitions is at /usr/share/alsa/alsa.conf. 88 89\subsection rawmidi_dev_names_default 90 91The default device is equal to hw device. The defaults are used: 92 93defaults.rawmidi.card 0 94defaults.rawmidi.device 0 95defaults.rawmidi.subdevice -1 96 97These defaults can be freely overwritten in local configuration files. 98 99Example: 100 101\code 102default 103\endcode 104 105\subsection rawmidi_dev_names_hw HW device 106 107The hw device description uses the hw plugin. The three arguments (in order: CARD,DEV,SUBDEV) 108specify card number or identifier, device number and subdevice number (-1 means any). 109 110Example: 111 112\code 113hw 114hw:0 115hw:0,0 116hw:supersonic,1 117hw:soundwave,1,2 118hw:DEV=1,CARD=soundwave,SUBDEV=2 119\endcode 120 121\section read_mode Read mode 122 123Optionally, incoming rawmidi bytes can be marked with timestamps. The library hides 124the kernel implementation (linux kernel 5.14+) and exports 125the \link ::snd_rawmidi_tread() \endlink function which returns the 126midi bytes marked with the identical timestamp in one iteration. 127 128The timestamping is available only on input streams. 129 130\section rawmidi_examples Examples 131 132The full featured examples with cross-links: 133 134\par Simple input/output test program 135\link example_test_rawmidi example code \endlink 136\par 137This example shows open and read/write rawmidi operations. 138 139*/ 140 141/** 142 * \example ../test/rawmidi.c 143 * \anchor example_test_rawmidi 144 * Shows open and read/write rawmidi operations. 145 */ 146 147#include "rawmidi_local.h" 148#include <stdio.h> 149#include <stdlib.h> 150#include <stdarg.h> 151#include <unistd.h> 152#include <string.h> 153 154/** 155 * \brief setup the default parameters 156 * \param rawmidi RawMidi handle 157 * \param params pointer to a snd_rawmidi_params_t structure 158 * \return 0 on success otherwise a negative error code 159 */ 160static int snd_rawmidi_params_default(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params) 161{ 162 assert(rawmidi); 163 assert(params); 164 params->buffer_size = page_size(); 165 params->avail_min = 1; 166 params->no_active_sensing = 1; 167 params->mode = 0; 168 memset(params->reserved, 0, sizeof(params->reserved)); 169 return 0; 170} 171 172static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, 173 const char *name, snd_config_t *rawmidi_root, 174 snd_config_t *rawmidi_conf, int mode) 175{ 176 const char *str; 177 char buf[256]; 178 int err; 179 snd_config_t *conf, *type_conf = NULL; 180 snd_config_iterator_t i, next; 181 snd_rawmidi_params_t params; 182 const char *id; 183 const char *lib = NULL, *open_name = NULL; 184 int (*open_func)(snd_rawmidi_t **, snd_rawmidi_t **, 185 const char *, snd_config_t *, snd_config_t *, int) = NULL; 186#ifndef PIC 187 extern void *snd_rawmidi_open_symbols(void); 188#endif 189 if (snd_config_get_type(rawmidi_conf) != SND_CONFIG_TYPE_COMPOUND) { 190 if (name) 191 SNDERR("Invalid type for RAWMIDI %s definition", name); 192 else 193 SNDERR("Invalid type for RAWMIDI definition"); 194 return -EINVAL; 195 } 196 err = snd_config_search(rawmidi_conf, "type", &conf); 197 if (err < 0) { 198 SNDERR("type is not defined"); 199 return err; 200 } 201 err = snd_config_get_id(conf, &id); 202 if (err < 0) { 203 SNDERR("unable to get id"); 204 return err; 205 } 206 err = snd_config_get_string(conf, &str); 207 if (err < 0) { 208 SNDERR("Invalid type for %s", id); 209 return err; 210 } 211 err = snd_config_search_definition(rawmidi_root, "rawmidi_type", str, &type_conf); 212 if (err >= 0) { 213 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) { 214 SNDERR("Invalid type for RAWMIDI type %s definition", str); 215 err = -EINVAL; 216 goto _err; 217 } 218 snd_config_for_each(i, next, type_conf) { 219 snd_config_t *n = snd_config_iterator_entry(i); 220 const char *id; 221 if (snd_config_get_id(n, &id) < 0) 222 continue; 223 if (strcmp(id, "comment") == 0) 224 continue; 225 if (strcmp(id, "lib") == 0) { 226 err = snd_config_get_string(n, &lib); 227 if (err < 0) { 228 SNDERR("Invalid type for %s", id); 229 goto _err; 230 } 231 continue; 232 } 233 if (strcmp(id, "open") == 0) { 234 err = snd_config_get_string(n, &open_name); 235 if (err < 0) { 236 SNDERR("Invalid type for %s", id); 237 goto _err; 238 } 239 continue; 240 } 241 SNDERR("Unknown field %s", id); 242 err = -EINVAL; 243 goto _err; 244 } 245 } 246 if (!open_name) { 247 open_name = buf; 248 snprintf(buf, sizeof(buf), "_snd_rawmidi_%s_open", str); 249 } 250#ifndef PIC 251 snd_rawmidi_open_symbols(); 252#endif 253 open_func = snd_dlobj_cache_get2(lib, open_name, 254 SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION), 1); 255 if (!open_func) { 256 err = -ENXIO; 257 goto _err; 258 } 259 if (type_conf) 260 snd_config_delete(type_conf); 261 err = open_func(inputp, outputp, name, rawmidi_root, rawmidi_conf, mode); 262 if (err < 0) 263 goto _err; 264 if (inputp) { 265 (*inputp)->open_func = open_func; 266 snd_rawmidi_params_default(*inputp, ¶ms); 267 err = snd_rawmidi_params(*inputp, ¶ms); 268 assert(err >= 0); 269 } 270 if (outputp) { 271 (*outputp)->open_func = open_func; 272 snd_rawmidi_params_default(*outputp, ¶ms); 273 err = snd_rawmidi_params(*outputp, ¶ms); 274 assert(err >= 0); 275 } 276 return 0; 277 278 _err: 279 if (open_func) 280 snd_dlobj_cache_put(open_func); 281 if (type_conf) 282 snd_config_delete(type_conf); 283 return err; 284} 285 286static int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, 287 snd_config_t *root, const char *name, int mode) 288{ 289 int err; 290 snd_config_t *rawmidi_conf; 291 err = snd_config_search_definition(root, "rawmidi", name, &rawmidi_conf); 292 if (err < 0) { 293 SNDERR("Unknown RawMidi %s", name); 294 return err; 295 } 296 err = snd_rawmidi_open_conf(inputp, outputp, name, root, rawmidi_conf, mode); 297 snd_config_delete(rawmidi_conf); 298 return err; 299} 300 301/** 302 * \brief Opens a new connection to the RawMidi interface. 303 * \param inputp Returned input handle (NULL if not wanted) 304 * \param outputp Returned output handle (NULL if not wanted) 305 * \param name ASCII identifier of the RawMidi handle 306 * \param mode Open mode 307 * \return 0 on success otherwise a negative error code 308 * 309 * Opens a new connection to the RawMidi interface specified with 310 * an ASCII identifier and mode. 311 */ 312int snd_rawmidi_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, 313 const char *name, int mode) 314{ 315 snd_config_t *top; 316 int err; 317 318 assert((inputp || outputp) && name); 319 if (_snd_is_ucm_device(name)) { 320 name = uc_mgr_alibcfg_by_device(&top, name); 321 if (name == NULL) 322 return -ENODEV; 323 } else { 324 err = snd_config_update_ref(&top); 325 if (err < 0) 326 return err; 327 } 328 err = snd_rawmidi_open_noupdate(inputp, outputp, top, name, mode); 329 snd_config_unref(top); 330 return err; 331} 332 333/** 334 * \brief Opens a new connection to the RawMidi interface using local configuration 335 * \param inputp Returned input handle (NULL if not wanted) 336 * \param outputp Returned output handle (NULL if not wanted) 337 * \param name ASCII identifier of the RawMidi handle 338 * \param mode Open mode 339 * \param lconf Local configuration 340 * \return 0 on success otherwise a negative error code 341 * 342 * Opens a new connection to the RawMidi interface specified with 343 * an ASCII identifier and mode. 344 */ 345int snd_rawmidi_open_lconf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, 346 const char *name, int mode, snd_config_t *lconf) 347{ 348 assert((inputp || outputp) && name && lconf); 349 return snd_rawmidi_open_noupdate(inputp, outputp, lconf, name, mode); 350} 351 352/** 353 * \brief close RawMidi handle 354 * \param rawmidi RawMidi handle 355 * \return 0 on success otherwise a negative error code 356 * 357 * Closes the specified RawMidi handle and frees all associated 358 * resources. 359 */ 360int snd_rawmidi_close(snd_rawmidi_t *rawmidi) 361{ 362 int err; 363 assert(rawmidi); 364 err = rawmidi->ops->close(rawmidi); 365 free(rawmidi->name); 366 if (rawmidi->open_func) 367 snd_dlobj_cache_put(rawmidi->open_func); 368 free(rawmidi); 369 return err; 370} 371 372/** 373 * \brief get identifier of RawMidi handle 374 * \param rawmidi a RawMidi handle 375 * \return ascii identifier of RawMidi handle 376 * 377 * Returns the ASCII identifier of given RawMidi handle. It's the same 378 * identifier specified in snd_rawmidi_open(). 379 */ 380const char *snd_rawmidi_name(snd_rawmidi_t *rawmidi) 381{ 382 assert(rawmidi); 383 return rawmidi->name; 384} 385 386/** 387 * \brief get type of RawMidi handle 388 * \param rawmidi a RawMidi handle 389 * \return type of RawMidi handle 390 * 391 * Returns the type #snd_rawmidi_type_t of given RawMidi handle. 392 */ 393snd_rawmidi_type_t snd_rawmidi_type(snd_rawmidi_t *rawmidi) 394{ 395 assert(rawmidi); 396 return rawmidi->type; 397} 398 399/** 400 * \brief get stream (direction) of RawMidi handle 401 * \param rawmidi a RawMidi handle 402 * \return stream of RawMidi handle 403 * 404 * Returns the stream #snd_rawmidi_stream_t of given RawMidi handle. 405 */ 406snd_rawmidi_stream_t snd_rawmidi_stream(snd_rawmidi_t *rawmidi) 407{ 408 assert(rawmidi); 409 return rawmidi->stream; 410} 411 412/** 413 * \brief get count of poll descriptors for RawMidi handle 414 * \param rawmidi RawMidi handle 415 * \return count of poll descriptors 416 */ 417int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rawmidi) 418{ 419 assert(rawmidi); 420 return 1; 421} 422 423/** 424 * \brief get poll descriptors 425 * \param rawmidi RawMidi handle 426 * \param pfds array of poll descriptors 427 * \param space space in the poll descriptor array 428 * \return count of filled descriptors 429 */ 430int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int space) 431{ 432 assert(rawmidi); 433 if (space >= 1) { 434 pfds->fd = rawmidi->poll_fd; 435 pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? (POLLOUT|POLLERR|POLLNVAL) : (POLLIN|POLLERR|POLLNVAL); 436 return 1; 437 } 438 return 0; 439} 440 441/** 442 * \brief get returned events from poll descriptors 443 * \param rawmidi rawmidi RawMidi handle 444 * \param pfds array of poll descriptors 445 * \param nfds count of poll descriptors 446 * \param revents returned events 447 * \return zero if success, otherwise a negative error code 448 */ 449int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) 450{ 451 assert(rawmidi && pfds && revents); 452 if (nfds == 1) { 453 *revents = pfds->revents; 454 return 0; 455 } 456 return -EINVAL; 457} 458 459/** 460 * \brief set nonblock mode 461 * \param rawmidi RawMidi handle 462 * \param nonblock 0 = block, 1 = nonblock mode 463 * \return 0 on success otherwise a negative error code 464 * 465 * The nonblock mode cannot be used when the stream is in 466 * #SND_RAWMIDI_APPEND state. 467 */ 468int snd_rawmidi_nonblock(snd_rawmidi_t *rawmidi, int nonblock) 469{ 470 int err; 471 assert(rawmidi); 472 assert(!(rawmidi->mode & SND_RAWMIDI_APPEND)); 473 if ((err = rawmidi->ops->nonblock(rawmidi, nonblock)) < 0) 474 return err; 475 if (nonblock) 476 rawmidi->mode |= SND_RAWMIDI_NONBLOCK; 477 else 478 rawmidi->mode &= ~SND_RAWMIDI_NONBLOCK; 479 return 0; 480} 481 482/** 483 * \brief get size of the snd_rawmidi_info_t structure in bytes 484 * \return size of the snd_rawmidi_info_t structure in bytes 485 */ 486size_t snd_rawmidi_info_sizeof() 487{ 488 return sizeof(snd_rawmidi_info_t); 489} 490 491/** 492 * \brief allocate a new snd_rawmidi_info_t structure 493 * \param info returned pointer 494 * \return 0 on success otherwise a negative error code if fails 495 * 496 * Allocates a new snd_rawmidi_params_t structure using the standard 497 * malloc C library function. 498 */ 499int snd_rawmidi_info_malloc(snd_rawmidi_info_t **info) 500{ 501 assert(info); 502 *info = calloc(1, sizeof(snd_rawmidi_info_t)); 503 if (!*info) 504 return -ENOMEM; 505 return 0; 506} 507 508/** 509 * \brief frees the snd_rawmidi_info_t structure 510 * \param info pointer to the snd_rawmidi_info_t structure to free 511 * 512 * Frees the given snd_rawmidi_params_t structure using the standard 513 * free C library function. 514 */ 515void snd_rawmidi_info_free(snd_rawmidi_info_t *info) 516{ 517 assert(info); 518 free(info); 519} 520 521/** 522 * \brief copy one snd_rawmidi_info_t structure to another 523 * \param dst destination snd_rawmidi_info_t structure 524 * \param src source snd_rawmidi_info_t structure 525 */ 526void snd_rawmidi_info_copy(snd_rawmidi_info_t *dst, const snd_rawmidi_info_t *src) 527{ 528 assert(dst && src); 529 *dst = *src; 530} 531 532/** 533 * \brief get rawmidi device number 534 * \param info pointer to a snd_rawmidi_info_t structure 535 * \return rawmidi device number 536 */ 537unsigned int snd_rawmidi_info_get_device(const snd_rawmidi_info_t *info) 538{ 539 assert(info); 540 return info->device; 541} 542 543/** 544 * \brief get rawmidi subdevice number 545 * \param info pointer to a snd_rawmidi_info_t structure 546 * \return rawmidi subdevice number 547 */ 548unsigned int snd_rawmidi_info_get_subdevice(const snd_rawmidi_info_t *info) 549{ 550 assert(info); 551 return info->subdevice; 552} 553 554/** 555 * \brief get rawmidi stream identification 556 * \param info pointer to a snd_rawmidi_info_t structure 557 * \return rawmidi stream identification 558 */ 559snd_rawmidi_stream_t snd_rawmidi_info_get_stream(const snd_rawmidi_info_t *info) 560{ 561 assert(info); 562 return info->stream; 563} 564 565/** 566 * \brief get rawmidi card number 567 * \param info pointer to a snd_rawmidi_info_t structure 568 * \return rawmidi card number 569 */ 570int snd_rawmidi_info_get_card(const snd_rawmidi_info_t *info) 571{ 572 assert(info); 573 return info->card; 574} 575 576/** 577 * \brief get rawmidi flags 578 * \param info pointer to a snd_rawmidi_info_t structure 579 * \return rawmidi flags 580 */ 581unsigned int snd_rawmidi_info_get_flags(const snd_rawmidi_info_t *info) 582{ 583 assert(info); 584 return info->flags; 585} 586 587/** 588 * \brief get rawmidi hardware driver identifier 589 * \param info pointer to a snd_rawmidi_info_t structure 590 * \return rawmidi hardware driver identifier 591 */ 592const char *snd_rawmidi_info_get_id(const snd_rawmidi_info_t *info) 593{ 594 assert(info); 595 return (const char *)info->id; 596} 597 598/** 599 * \brief get rawmidi hardware driver name 600 * \param info pointer to a snd_rawmidi_info_t structure 601 * \return rawmidi hardware driver name 602 */ 603const char *snd_rawmidi_info_get_name(const snd_rawmidi_info_t *info) 604{ 605 assert(info); 606 return (const char *)info->name; 607} 608 609/** 610 * \brief get rawmidi subdevice name 611 * \param info pointer to a snd_rawmidi_info_t structure 612 * \return rawmidi subdevice name 613 */ 614const char *snd_rawmidi_info_get_subdevice_name(const snd_rawmidi_info_t *info) 615{ 616 assert(info); 617 return (const char *)info->subname; 618} 619 620/** 621 * \brief get rawmidi count of subdevices 622 * \param info pointer to a snd_rawmidi_info_t structure 623 * \return rawmidi count of subdevices 624 */ 625unsigned int snd_rawmidi_info_get_subdevices_count(const snd_rawmidi_info_t *info) 626{ 627 assert(info); 628 return info->subdevices_count; 629} 630 631/** 632 * \brief get rawmidi available count of subdevices 633 * \param info pointer to a snd_rawmidi_info_t structure 634 * \return rawmidi available count of subdevices 635 */ 636unsigned int snd_rawmidi_info_get_subdevices_avail(const snd_rawmidi_info_t *info) 637{ 638 assert(info); 639 return info->subdevices_avail; 640} 641 642/** 643 * \brief set rawmidi device number 644 * \param info pointer to a snd_rawmidi_info_t structure 645 * \param val device number 646 */ 647void snd_rawmidi_info_set_device(snd_rawmidi_info_t *info, unsigned int val) 648{ 649 assert(info); 650 info->device = val; 651} 652 653/** 654 * \brief set rawmidi subdevice number 655 * \param info pointer to a snd_rawmidi_info_t structure 656 * \param val subdevice number 657 */ 658void snd_rawmidi_info_set_subdevice(snd_rawmidi_info_t *info, unsigned int val) 659{ 660 assert(info); 661 info->subdevice = val; 662} 663 664/** 665 * \brief set rawmidi stream identifier 666 * \param info pointer to a snd_rawmidi_info_t structure 667 * \param val rawmidi stream identifier 668 */ 669void snd_rawmidi_info_set_stream(snd_rawmidi_info_t *info, snd_rawmidi_stream_t val) 670{ 671 assert(info); 672 info->stream = val; 673} 674 675/** 676 * \brief get information about RawMidi handle 677 * \param rawmidi RawMidi handle 678 * \param info pointer to a snd_rawmidi_info_t structure to be filled 679 * \return 0 on success otherwise a negative error code 680 */ 681int snd_rawmidi_info(snd_rawmidi_t *rawmidi, snd_rawmidi_info_t * info) 682{ 683 assert(rawmidi); 684 assert(info); 685 return rawmidi->ops->info(rawmidi, info); 686} 687 688/** 689 * \brief get size of the snd_rawmidi_params_t structure in bytes 690 * \return size of the snd_rawmidi_params_t structure in bytes 691 */ 692size_t snd_rawmidi_params_sizeof() 693{ 694 return sizeof(snd_rawmidi_params_t); 695} 696 697/** 698 * \brief allocate the snd_rawmidi_params_t structure 699 * \param params returned pointer 700 * \return 0 on success otherwise a negative error code if fails 701 * 702 * Allocates a new snd_rawmidi_params_t structure using the standard 703 * malloc C library function. 704 */ 705int snd_rawmidi_params_malloc(snd_rawmidi_params_t **params) 706{ 707 assert(params); 708 *params = calloc(1, sizeof(snd_rawmidi_params_t)); 709 if (!*params) 710 return -ENOMEM; 711 return 0; 712} 713 714/** 715 * \brief frees the snd_rawmidi_params_t structure 716 * \param params pointer to the #snd_rawmidi_params_t structure to free 717 * 718 * Frees the given snd_rawmidi_params_t structure using the standard 719 * free C library function. 720 */ 721void snd_rawmidi_params_free(snd_rawmidi_params_t *params) 722{ 723 assert(params); 724 free(params); 725} 726 727/** 728 * \brief copy one snd_rawmidi_params_t structure to another 729 * \param dst destination snd_rawmidi_params_t structure 730 * \param src source snd_rawmidi_params_t structure 731 */ 732void snd_rawmidi_params_copy(snd_rawmidi_params_t *dst, const snd_rawmidi_params_t *src) 733{ 734 assert(dst && src); 735 *dst = *src; 736} 737 738/** 739 * \brief set rawmidi I/O ring buffer size 740 * \param rawmidi RawMidi handle 741 * \param params pointer to a snd_rawmidi_params_t structure 742 * \param val size in bytes 743 * \return 0 on success otherwise a negative error code 744 */ 745#ifndef DOXYGEN 746int snd_rawmidi_params_set_buffer_size(snd_rawmidi_t *rawmidi ATTRIBUTE_UNUSED, snd_rawmidi_params_t *params, size_t val) 747#else 748int snd_rawmidi_params_set_buffer_size(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params, size_t val) 749#endif 750{ 751 assert(rawmidi && params); 752 assert(val > params->avail_min); 753 params->buffer_size = val; 754 return 0; 755} 756 757/** 758 * \brief get rawmidi I/O ring buffer size 759 * \param params pointer to a snd_rawmidi_params_t structure 760 * \return size of rawmidi I/O ring buffer in bytes 761 */ 762size_t snd_rawmidi_params_get_buffer_size(const snd_rawmidi_params_t *params) 763{ 764 assert(params); 765 return params->buffer_size; 766} 767 768/** 769 * \brief set minimum available bytes in rawmidi I/O ring buffer for wakeup 770 * \param rawmidi RawMidi handle 771 * \param params pointer to a snd_rawmidi_params_t structure 772 * \param val desired value 773 */ 774#ifndef DOXYGEN 775int snd_rawmidi_params_set_avail_min(snd_rawmidi_t *rawmidi ATTRIBUTE_UNUSED, snd_rawmidi_params_t *params, size_t val) 776#else 777int snd_rawmidi_params_set_avail_min(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params, size_t val) 778#endif 779{ 780 assert(rawmidi && params); 781 assert(val < params->buffer_size); 782 params->avail_min = val; 783 return 0; 784} 785 786/** 787 * \brief get minimum available bytes in rawmidi I/O ring buffer for wakeup 788 * \param params pointer to snd_rawmidi_params_t structure 789 * \return minimum available bytes 790 */ 791size_t snd_rawmidi_params_get_avail_min(const snd_rawmidi_params_t *params) 792{ 793 assert(params); 794 return params->avail_min; 795} 796 797/** 798 * \brief set no-active-sensing action on snd_rawmidi_close() 799 * \param rawmidi RawMidi handle 800 * \param params pointer to snd_rawmidi_params_t structure 801 * \param val value: 0 = enable to send the active sensing message, 1 = disable 802 * \return 0 on success otherwise a negative error code 803 */ 804#ifndef DOXYGEN 805int snd_rawmidi_params_set_no_active_sensing(snd_rawmidi_t *rawmidi ATTRIBUTE_UNUSED, snd_rawmidi_params_t *params, int val) 806#else 807int snd_rawmidi_params_set_no_active_sensing(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params, int val) 808#endif 809{ 810 assert(rawmidi && params); 811 params->no_active_sensing = val; 812 return 0; 813} 814 815/** 816 * \brief get no-active-sensing action status 817 * \param params pointer to snd_rawmidi_params_t structure 818 * \return the current status (0 = enable, 1 = disable the active sensing message) 819 */ 820int snd_rawmidi_params_get_no_active_sensing(const snd_rawmidi_params_t *params) 821{ 822 assert(params); 823 return params->no_active_sensing; 824} 825 826/** 827 * \brief set read mode 828 * \param rawmidi RawMidi handle 829 * \param params pointer to snd_rawmidi_params_t structure 830 * \param val type of read_mode 831 * \return 0 on success, otherwise a negative error code. 832 * 833 * Notable error codes: 834 * -EINVAL - "val" is invalid 835 * -ENOTSUP - mode is not supported 836 * 837 */ 838int snd_rawmidi_params_set_read_mode(const snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params, snd_rawmidi_read_mode_t val) 839{ 840 unsigned int framing; 841 assert(rawmidi && params); 842 843 switch (val) { 844 case SND_RAWMIDI_READ_STANDARD: 845 framing = SNDRV_RAWMIDI_MODE_FRAMING_NONE; 846 break; 847 case SND_RAWMIDI_READ_TSTAMP: 848 if (rawmidi->ops->tread == NULL) 849 return -ENOTSUP; 850 framing = SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP; 851 break; 852 default: 853 return -EINVAL; 854 } 855 856 if (framing != SNDRV_RAWMIDI_MODE_FRAMING_NONE && 857 (rawmidi->version < SNDRV_PROTOCOL_VERSION(2, 0, 2) || rawmidi->stream != SND_RAWMIDI_STREAM_INPUT)) 858 return -ENOTSUP; 859 params->mode = (params->mode & ~SNDRV_RAWMIDI_MODE_FRAMING_MASK) | framing; 860 return 0; 861} 862 863/** 864 * \brief get current read mode 865 * \param params pointer to snd_rawmidi_params_t structure 866 * \return the current read mode (see enum) 867 */ 868snd_rawmidi_read_mode_t snd_rawmidi_params_get_read_mode(const snd_rawmidi_params_t *params) 869{ 870 unsigned int framing; 871 872 assert(params); 873 framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK; 874 if (framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) 875 return SND_RAWMIDI_READ_TSTAMP; 876 return SND_RAWMIDI_READ_STANDARD; 877} 878 879/** 880 * \brief sets clock type for tstamp type framing 881 * \param rawmidi RawMidi handle 882 * \param params pointer to snd_rawmidi_params_t structure 883 * \param val one of the SND_RAWMIDI_CLOCK_* constants 884 * \return 0 on success, otherwise a negative error code. 885 * 886 * Notable error codes: 887 * -EINVAL - "val" is invalid 888 * -ENOTSUP - Kernel is too old to support framing. 889 * 890 */ 891int snd_rawmidi_params_set_clock_type(const snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params, snd_rawmidi_clock_t val) 892{ 893 assert(rawmidi && params); 894 if (val > SNDRV_RAWMIDI_MODE_CLOCK_MASK >> SNDRV_RAWMIDI_MODE_CLOCK_SHIFT) 895 return -EINVAL; 896 if (val != SNDRV_RAWMIDI_MODE_CLOCK_NONE && 897 (rawmidi->version < SNDRV_PROTOCOL_VERSION(2, 0, 2) || rawmidi->stream != SND_RAWMIDI_STREAM_INPUT)) 898 return -ENOTSUP; 899 params->mode = (params->mode & ~SNDRV_RAWMIDI_MODE_CLOCK_MASK) + (val << SNDRV_RAWMIDI_MODE_CLOCK_SHIFT); 900 return 0; 901} 902 903/** 904 * \brief get current clock type (for tstamp type framing) 905 * \param params pointer to snd_rawmidi_params_t structure 906 * \return the current clock type (one of the SND_RAWMIDI_CLOCK_* constants) 907 */ 908snd_rawmidi_clock_t snd_rawmidi_params_get_clock_type(const snd_rawmidi_params_t *params) 909{ 910 assert(params); 911 return (params->mode & SNDRV_RAWMIDI_MODE_CLOCK_MASK) >> SNDRV_RAWMIDI_MODE_CLOCK_SHIFT; 912} 913 914 915/** 916 * \brief set parameters about rawmidi stream 917 * \param rawmidi RawMidi handle 918 * \param params pointer to a snd_rawmidi_params_t structure to be filled 919 * \return 0 on success otherwise a negative error code 920 */ 921int snd_rawmidi_params(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t * params) 922{ 923 int err; 924 assert(rawmidi); 925 assert(params); 926 err = rawmidi->ops->params(rawmidi, params); 927 if (err < 0) 928 return err; 929 rawmidi->buffer_size = params->buffer_size; 930 rawmidi->avail_min = params->avail_min; 931 rawmidi->no_active_sensing = params->no_active_sensing; 932 rawmidi->params_mode = rawmidi->version < SNDRV_PROTOCOL_VERSION(2, 0, 2) ? 0 : params->mode; 933 return 0; 934} 935 936/** 937 * \brief get current parameters about rawmidi stream 938 * \param rawmidi RawMidi handle 939 * \param params pointer to a snd_rawmidi_params_t structure to be filled 940 * \return 0 on success otherwise a negative error code 941 */ 942int snd_rawmidi_params_current(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params) 943{ 944 assert(rawmidi); 945 assert(params); 946 params->buffer_size = rawmidi->buffer_size; 947 params->avail_min = rawmidi->avail_min; 948 params->no_active_sensing = rawmidi->no_active_sensing; 949 params->mode = rawmidi->params_mode; 950 return 0; 951} 952 953/** 954 * \brief get size of the snd_rawmidi_status_t structure in bytes 955 * \return size of the snd_rawmidi_status_t structure in bytes 956 */ 957size_t snd_rawmidi_status_sizeof() 958{ 959 return sizeof(snd_rawmidi_status_t); 960} 961 962/** 963 * \brief allocate the snd_rawmidi_status_t structure 964 * \param ptr returned pointer 965 * \return 0 on success otherwise a negative error code if fails 966 * 967 * Allocates a new snd_rawmidi_status_t structure using the standard 968 * malloc C library function. 969 */ 970int snd_rawmidi_status_malloc(snd_rawmidi_status_t **ptr) 971{ 972 assert(ptr); 973 *ptr = calloc(1, sizeof(snd_rawmidi_status_t)); 974 if (!*ptr) 975 return -ENOMEM; 976 return 0; 977} 978 979/** 980 * \brief frees the snd_rawmidi_status_t structure 981 * \param status pointer to the snd_rawmidi_status_t structure to free 982 * 983 * Frees the given snd_rawmidi_status_t structure using the standard 984 * free C library function. 985 */ 986void snd_rawmidi_status_free(snd_rawmidi_status_t *status) 987{ 988 assert(status); 989 free(status); 990} 991 992/** 993 * \brief copy one snd_rawmidi_status_t structure to another 994 * \param dst destination snd_rawmidi_status_t structure 995 * \param src source snd_rawmidi_status_t structure 996 */ 997void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status_t *src) 998{ 999 assert(dst && src); 1000 *dst = *src; 1001} 1002 1003/** 1004 * \brief get the start timestamp 1005 * \param status pointer to a snd_rawmidi_status_t structure 1006 * \param tstamp returned timestamp value 1007 */ 1008void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *status, snd_htimestamp_t *tstamp) 1009{ 1010 assert(status && tstamp); 1011 *tstamp = status->tstamp; 1012} 1013 1014/** 1015 * \brief get current available bytes in the rawmidi I/O ring buffer 1016 * \param status pointer to a snd_rawmidi_status_t structure 1017 * \return current available bytes in the rawmidi I/O ring buffer 1018 */ 1019size_t snd_rawmidi_status_get_avail(const snd_rawmidi_status_t *status) 1020{ 1021 assert(status); 1022 return status->avail; 1023} 1024 1025/** 1026 * \brief get count of xruns 1027 * \param status pointer to a snd_rawmidi_status_t structure 1028 * \return count of xruns 1029 */ 1030size_t snd_rawmidi_status_get_xruns(const snd_rawmidi_status_t *status) 1031{ 1032 assert(status); 1033 return status->xruns; 1034} 1035 1036/** 1037 * \brief get status of rawmidi stream 1038 * \param rawmidi RawMidi handle 1039 * \param status pointer to a snd_rawmidi_status_t structure to be filled 1040 * \return 0 on success otherwise a negative error code 1041 */ 1042int snd_rawmidi_status(snd_rawmidi_t *rawmidi, snd_rawmidi_status_t * status) 1043{ 1044 assert(rawmidi); 1045 assert(status); 1046 return rawmidi->ops->status(rawmidi, status); 1047} 1048 1049/** 1050 * \brief drop all bytes in the rawmidi I/O ring buffer immediately 1051 * \param rawmidi RawMidi handle 1052 * \return 0 on success otherwise a negative error code 1053 */ 1054int snd_rawmidi_drop(snd_rawmidi_t *rawmidi) 1055{ 1056 assert(rawmidi); 1057 return rawmidi->ops->drop(rawmidi); 1058} 1059 1060/** 1061 * \brief drain all bytes in the rawmidi I/O ring buffer 1062 * \param rawmidi RawMidi handle 1063 * \return 0 on success otherwise a negative error code 1064 * 1065 * Waits until all MIDI bytes are not drained (sent) to the 1066 * hardware device. 1067 */ 1068int snd_rawmidi_drain(snd_rawmidi_t *rawmidi) 1069{ 1070 assert(rawmidi); 1071 return rawmidi->ops->drain(rawmidi); 1072} 1073 1074/** 1075 * \brief write MIDI bytes to MIDI stream 1076 * \param rawmidi RawMidi handle 1077 * \param buffer buffer containing MIDI bytes 1078 * \param size output buffer size in bytes 1079 */ 1080ssize_t snd_rawmidi_write(snd_rawmidi_t *rawmidi, const void *buffer, size_t size) 1081{ 1082 assert(rawmidi); 1083 assert(rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT); 1084 assert(buffer || size == 0); 1085 return rawmidi->ops->write(rawmidi, buffer, size); 1086} 1087 1088/** 1089 * \brief read MIDI bytes from MIDI stream 1090 * \param rawmidi RawMidi handle 1091 * \param buffer buffer to store the input MIDI bytes 1092 * \param size input buffer size in bytes 1093 * \retval count of MIDI bytes otherwise a negative error code 1094 */ 1095ssize_t snd_rawmidi_read(snd_rawmidi_t *rawmidi, void *buffer, size_t size) 1096{ 1097 assert(rawmidi); 1098 assert(rawmidi->stream == SND_RAWMIDI_STREAM_INPUT); 1099 if ((rawmidi->params_mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK) == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) 1100 size &= ~(sizeof(struct snd_rawmidi_framing_tstamp) - 1); 1101 assert(buffer || size == 0); 1102 return (rawmidi->ops->read)(rawmidi, buffer, size); 1103} 1104 1105/** 1106 * \brief read MIDI bytes from MIDI stream with timestamp 1107 * \param rawmidi RawMidi handle 1108 * \param[out] tstamp timestamp for the returned MIDI bytes 1109 * \param buffer buffer to store the input MIDI bytes 1110 * \param size input buffer size in bytes 1111 * \retval count of MIDI bytes otherwise a negative error code 1112 */ 1113ssize_t snd_rawmidi_tread(snd_rawmidi_t *rawmidi, struct timespec *tstamp, void *buffer, size_t size) 1114{ 1115 assert(rawmidi); 1116 assert(rawmidi->stream == SND_RAWMIDI_STREAM_INPUT); 1117 assert(buffer || size == 0); 1118 if ((rawmidi->params_mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK) != SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) 1119 return -EINVAL; 1120 if (rawmidi->ops->tread == NULL) 1121 return -ENOTSUP; 1122 return (rawmidi->ops->tread)(rawmidi, tstamp, buffer, size); 1123} 1124 1125#ifndef DOXYGEN 1126/* 1127 * internal API functions for obtaining UMP info from rawmidi instance 1128 */ 1129int _snd_rawmidi_ump_endpoint_info(snd_rawmidi_t *rmidi, void *info) 1130{ 1131 if (!rmidi->ops->ump_endpoint_info) 1132 return -ENXIO; 1133 return rmidi->ops->ump_endpoint_info(rmidi, info); 1134} 1135 1136int _snd_rawmidi_ump_block_info(snd_rawmidi_t *rmidi, void *info) 1137{ 1138 if (!rmidi->ops->ump_block_info) 1139 return -ENXIO; 1140 return rmidi->ops->ump_block_info(rmidi, info); 1141} 1142#endif /* DOXYGEN */ 1143