1d5ac70f0Sopenharmony_ci/* SPDX-License-Identifier: LGPL-2.1+ */ 2d5ac70f0Sopenharmony_ci/** 3d5ac70f0Sopenharmony_ci * \file rawmidi/ump.c 4d5ac70f0Sopenharmony_ci * \brief Universal MIDI Protocol (UMP) Interface 5d5ac70f0Sopenharmony_ci */ 6d5ac70f0Sopenharmony_ci 7d5ac70f0Sopenharmony_ci#include "rawmidi_local.h" 8d5ac70f0Sopenharmony_ci#include "ump_local.h" 9d5ac70f0Sopenharmony_ci 10d5ac70f0Sopenharmony_cistatic int get_rawmidi_flags(snd_ump_t *ump) 11d5ac70f0Sopenharmony_ci{ 12d5ac70f0Sopenharmony_ci snd_rawmidi_info_t info; 13d5ac70f0Sopenharmony_ci int err; 14d5ac70f0Sopenharmony_ci 15d5ac70f0Sopenharmony_ci err = snd_rawmidi_info(ump->rawmidi, &info); 16d5ac70f0Sopenharmony_ci if (err < 0) 17d5ac70f0Sopenharmony_ci return err; 18d5ac70f0Sopenharmony_ci if (!(info.flags & SNDRV_RAWMIDI_INFO_UMP)) 19d5ac70f0Sopenharmony_ci return -EINVAL; 20d5ac70f0Sopenharmony_ci ump->flags = info.flags; 21d5ac70f0Sopenharmony_ci return 0; 22d5ac70f0Sopenharmony_ci} 23d5ac70f0Sopenharmony_ci 24d5ac70f0Sopenharmony_ci/** 25d5ac70f0Sopenharmony_ci * \brief Opens a new connection to the UMP interface. 26d5ac70f0Sopenharmony_ci * \param inputp Returned input handle (NULL if not wanted) 27d5ac70f0Sopenharmony_ci * \param outputp Returned output handle (NULL if not wanted) 28d5ac70f0Sopenharmony_ci * \param name ASCII identifier of the UMP handle 29d5ac70f0Sopenharmony_ci * \param mode Open mode 30d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 31d5ac70f0Sopenharmony_ci * 32d5ac70f0Sopenharmony_ci * Opens a new connection to the UMP interface specified with 33d5ac70f0Sopenharmony_ci * an ASCII identifier and mode. 34d5ac70f0Sopenharmony_ci */ 35d5ac70f0Sopenharmony_ciint snd_ump_open(snd_ump_t **inputp, snd_ump_t **outputp, const char *name, 36d5ac70f0Sopenharmony_ci int mode) 37d5ac70f0Sopenharmony_ci{ 38d5ac70f0Sopenharmony_ci snd_ump_t *input = NULL, *output = NULL; 39d5ac70f0Sopenharmony_ci int err; 40d5ac70f0Sopenharmony_ci 41d5ac70f0Sopenharmony_ci if (inputp) 42d5ac70f0Sopenharmony_ci *inputp = NULL; 43d5ac70f0Sopenharmony_ci if (outputp) 44d5ac70f0Sopenharmony_ci *outputp = NULL; 45d5ac70f0Sopenharmony_ci if (!inputp && !outputp) 46d5ac70f0Sopenharmony_ci return -EINVAL; 47d5ac70f0Sopenharmony_ci 48d5ac70f0Sopenharmony_ci err = -ENOMEM; 49d5ac70f0Sopenharmony_ci if (inputp) { 50d5ac70f0Sopenharmony_ci input = calloc(1, sizeof(*input)); 51d5ac70f0Sopenharmony_ci if (!input) 52d5ac70f0Sopenharmony_ci goto error; 53d5ac70f0Sopenharmony_ci input->is_input = 1; 54d5ac70f0Sopenharmony_ci } 55d5ac70f0Sopenharmony_ci if (outputp) { 56d5ac70f0Sopenharmony_ci output = calloc(1, sizeof(*output)); 57d5ac70f0Sopenharmony_ci if (!output) 58d5ac70f0Sopenharmony_ci goto error; 59d5ac70f0Sopenharmony_ci } 60d5ac70f0Sopenharmony_ci 61d5ac70f0Sopenharmony_ci err = snd_rawmidi_open(input ? &input->rawmidi : NULL, 62d5ac70f0Sopenharmony_ci output ? &output->rawmidi : NULL, 63d5ac70f0Sopenharmony_ci name, mode | _SND_RAWMIDI_OPEN_UMP); 64d5ac70f0Sopenharmony_ci if (err < 0) 65d5ac70f0Sopenharmony_ci goto error; 66d5ac70f0Sopenharmony_ci 67d5ac70f0Sopenharmony_ci if (input) { 68d5ac70f0Sopenharmony_ci err = get_rawmidi_flags(input); 69d5ac70f0Sopenharmony_ci if (err < 0) 70d5ac70f0Sopenharmony_ci goto error; 71d5ac70f0Sopenharmony_ci } 72d5ac70f0Sopenharmony_ci if (output) { 73d5ac70f0Sopenharmony_ci err = get_rawmidi_flags(output); 74d5ac70f0Sopenharmony_ci if (err < 0) 75d5ac70f0Sopenharmony_ci goto error; 76d5ac70f0Sopenharmony_ci } 77d5ac70f0Sopenharmony_ci 78d5ac70f0Sopenharmony_ci if (inputp) 79d5ac70f0Sopenharmony_ci *inputp = input; 80d5ac70f0Sopenharmony_ci if (outputp) 81d5ac70f0Sopenharmony_ci *outputp = output; 82d5ac70f0Sopenharmony_ci 83d5ac70f0Sopenharmony_ci return 0; 84d5ac70f0Sopenharmony_ci 85d5ac70f0Sopenharmony_ci error: 86d5ac70f0Sopenharmony_ci if (input) { 87d5ac70f0Sopenharmony_ci if (input->rawmidi) 88d5ac70f0Sopenharmony_ci snd_rawmidi_close(input->rawmidi); 89d5ac70f0Sopenharmony_ci free(input); 90d5ac70f0Sopenharmony_ci } 91d5ac70f0Sopenharmony_ci if (output) { 92d5ac70f0Sopenharmony_ci if (output->rawmidi) 93d5ac70f0Sopenharmony_ci snd_rawmidi_close(output->rawmidi); 94d5ac70f0Sopenharmony_ci free(output); 95d5ac70f0Sopenharmony_ci } 96d5ac70f0Sopenharmony_ci return err; 97d5ac70f0Sopenharmony_ci} 98d5ac70f0Sopenharmony_ci 99d5ac70f0Sopenharmony_ci/** 100d5ac70f0Sopenharmony_ci * \brief close UMP handle 101d5ac70f0Sopenharmony_ci * \param ump UMP handle 102d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 103d5ac70f0Sopenharmony_ci * 104d5ac70f0Sopenharmony_ci * Closes the specified UMP handle and frees all associated 105d5ac70f0Sopenharmony_ci * resources. 106d5ac70f0Sopenharmony_ci */ 107d5ac70f0Sopenharmony_ciint snd_ump_close(snd_ump_t *ump) 108d5ac70f0Sopenharmony_ci{ 109d5ac70f0Sopenharmony_ci int err; 110d5ac70f0Sopenharmony_ci 111d5ac70f0Sopenharmony_ci err = snd_rawmidi_close(ump->rawmidi); 112d5ac70f0Sopenharmony_ci free(ump); 113d5ac70f0Sopenharmony_ci return err; 114d5ac70f0Sopenharmony_ci} 115d5ac70f0Sopenharmony_ci 116d5ac70f0Sopenharmony_ci/** 117d5ac70f0Sopenharmony_ci * \brief get RawMidi instance associated with the UMP handle 118d5ac70f0Sopenharmony_ci * \param ump UMP handle 119d5ac70f0Sopenharmony_ci * \return the associated RawMidi handle 120d5ac70f0Sopenharmony_ci * 121d5ac70f0Sopenharmony_ci * Returns the associated RawMidi instance with the given UMP handle 122d5ac70f0Sopenharmony_ci */ 123d5ac70f0Sopenharmony_cisnd_rawmidi_t *snd_ump_rawmidi(snd_ump_t *ump) 124d5ac70f0Sopenharmony_ci{ 125d5ac70f0Sopenharmony_ci return ump->rawmidi; 126d5ac70f0Sopenharmony_ci} 127d5ac70f0Sopenharmony_ci 128d5ac70f0Sopenharmony_ci/** 129d5ac70f0Sopenharmony_ci * \brief get identifier of UMP handle 130d5ac70f0Sopenharmony_ci * \param ump UMP handle 131d5ac70f0Sopenharmony_ci * \return ascii identifier of UMP handle 132d5ac70f0Sopenharmony_ci * 133d5ac70f0Sopenharmony_ci * Returns the ASCII identifier of given UMP handle. It's the same 134d5ac70f0Sopenharmony_ci * identifier specified in snd_ump_open(). 135d5ac70f0Sopenharmony_ci */ 136d5ac70f0Sopenharmony_ciconst char *snd_ump_name(snd_ump_t *ump) 137d5ac70f0Sopenharmony_ci{ 138d5ac70f0Sopenharmony_ci return snd_rawmidi_name(ump->rawmidi); 139d5ac70f0Sopenharmony_ci} 140d5ac70f0Sopenharmony_ci 141d5ac70f0Sopenharmony_ci/** 142d5ac70f0Sopenharmony_ci * \brief get count of poll descriptors for UMP handle 143d5ac70f0Sopenharmony_ci * \param ump UMP handle 144d5ac70f0Sopenharmony_ci * \return count of poll descriptors 145d5ac70f0Sopenharmony_ci */ 146d5ac70f0Sopenharmony_ciint snd_ump_poll_descriptors_count(snd_ump_t *ump) 147d5ac70f0Sopenharmony_ci{ 148d5ac70f0Sopenharmony_ci return snd_rawmidi_poll_descriptors_count(ump->rawmidi); 149d5ac70f0Sopenharmony_ci} 150d5ac70f0Sopenharmony_ci 151d5ac70f0Sopenharmony_ci/** 152d5ac70f0Sopenharmony_ci * \brief get poll descriptors 153d5ac70f0Sopenharmony_ci * \param ump UMP handle 154d5ac70f0Sopenharmony_ci * \param pfds array of poll descriptors 155d5ac70f0Sopenharmony_ci * \param space space in the poll descriptor array 156d5ac70f0Sopenharmony_ci * \return count of filled descriptors 157d5ac70f0Sopenharmony_ci */ 158d5ac70f0Sopenharmony_ciint snd_ump_poll_descriptors(snd_ump_t *ump, struct pollfd *pfds, 159d5ac70f0Sopenharmony_ci unsigned int space) 160d5ac70f0Sopenharmony_ci{ 161d5ac70f0Sopenharmony_ci return snd_rawmidi_poll_descriptors(ump->rawmidi, pfds, space); 162d5ac70f0Sopenharmony_ci} 163d5ac70f0Sopenharmony_ci 164d5ac70f0Sopenharmony_ci/** 165d5ac70f0Sopenharmony_ci * \brief get returned events from poll descriptors 166d5ac70f0Sopenharmony_ci * \param ump UMP handle 167d5ac70f0Sopenharmony_ci * \param pfds array of poll descriptors 168d5ac70f0Sopenharmony_ci * \param nfds count of poll descriptors 169d5ac70f0Sopenharmony_ci * \param revents returned events 170d5ac70f0Sopenharmony_ci * \return zero if success, otherwise a negative error code 171d5ac70f0Sopenharmony_ci */ 172d5ac70f0Sopenharmony_ciint snd_ump_poll_descriptors_revents(snd_ump_t *ump, struct pollfd *pfds, 173d5ac70f0Sopenharmony_ci unsigned int nfds, unsigned short *revents) 174d5ac70f0Sopenharmony_ci{ 175d5ac70f0Sopenharmony_ci return snd_rawmidi_poll_descriptors_revents(ump->rawmidi, pfds, nfds, 176d5ac70f0Sopenharmony_ci revents); 177d5ac70f0Sopenharmony_ci} 178d5ac70f0Sopenharmony_ci 179d5ac70f0Sopenharmony_ci/** 180d5ac70f0Sopenharmony_ci * \brief set nonblock mode 181d5ac70f0Sopenharmony_ci * \param ump UMP handle 182d5ac70f0Sopenharmony_ci * \param nonblock 0 = block, 1 = nonblock mode 183d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 184d5ac70f0Sopenharmony_ci * 185d5ac70f0Sopenharmony_ci * The nonblock mode cannot be used when the stream is in 186d5ac70f0Sopenharmony_ci * #SND_RAWMIDI_APPEND state. 187d5ac70f0Sopenharmony_ci */ 188d5ac70f0Sopenharmony_ciint snd_ump_nonblock(snd_ump_t *ump, int nonblock) 189d5ac70f0Sopenharmony_ci{ 190d5ac70f0Sopenharmony_ci return snd_rawmidi_nonblock(ump->rawmidi, nonblock); 191d5ac70f0Sopenharmony_ci} 192d5ac70f0Sopenharmony_ci 193d5ac70f0Sopenharmony_ci/** 194d5ac70f0Sopenharmony_ci * \brief get information about associated RawMidi handle 195d5ac70f0Sopenharmony_ci * \param ump UMP handle 196d5ac70f0Sopenharmony_ci * \param info pointer to a snd_rawmidi_info_t structure to be filled 197d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 198d5ac70f0Sopenharmony_ci */ 199d5ac70f0Sopenharmony_ciint snd_ump_rawmidi_info(snd_ump_t *ump, snd_rawmidi_info_t *info) 200d5ac70f0Sopenharmony_ci{ 201d5ac70f0Sopenharmony_ci return snd_rawmidi_info(ump->rawmidi, info); 202d5ac70f0Sopenharmony_ci} 203d5ac70f0Sopenharmony_ci 204d5ac70f0Sopenharmony_ci/** 205d5ac70f0Sopenharmony_ci * \brief set parameters about associated RawMidi stream 206d5ac70f0Sopenharmony_ci * \param ump UMP handle 207d5ac70f0Sopenharmony_ci * \param params pointer to a snd_rawmidi_params_t structure to be filled 208d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 209d5ac70f0Sopenharmony_ci */ 210d5ac70f0Sopenharmony_ciint snd_ump_rawmidi_params(snd_ump_t *ump, snd_rawmidi_params_t *params) 211d5ac70f0Sopenharmony_ci{ 212d5ac70f0Sopenharmony_ci return snd_rawmidi_params(ump->rawmidi, params); 213d5ac70f0Sopenharmony_ci} 214d5ac70f0Sopenharmony_ci 215d5ac70f0Sopenharmony_ci/** 216d5ac70f0Sopenharmony_ci * \brief get current parameters about associated RawMidi stream 217d5ac70f0Sopenharmony_ci * \param ump UMP handle 218d5ac70f0Sopenharmony_ci * \param params pointer to a snd_rawmidi_params_t structure to be filled 219d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 220d5ac70f0Sopenharmony_ci */ 221d5ac70f0Sopenharmony_ciint snd_ump_rawmidi_params_current(snd_ump_t *ump, snd_rawmidi_params_t *params) 222d5ac70f0Sopenharmony_ci{ 223d5ac70f0Sopenharmony_ci return snd_rawmidi_params_current(ump->rawmidi, params); 224d5ac70f0Sopenharmony_ci} 225d5ac70f0Sopenharmony_ci 226d5ac70f0Sopenharmony_ci/** 227d5ac70f0Sopenharmony_ci * \brief get status of associated RawMidi stream 228d5ac70f0Sopenharmony_ci * \param ump UMP handle 229d5ac70f0Sopenharmony_ci * \param status pointer to a snd_rawmidi_status_t structure to be filled 230d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 231d5ac70f0Sopenharmony_ci */ 232d5ac70f0Sopenharmony_ciint snd_ump_rawmidi_status(snd_ump_t *ump, snd_rawmidi_status_t *status) 233d5ac70f0Sopenharmony_ci{ 234d5ac70f0Sopenharmony_ci return snd_rawmidi_status(ump->rawmidi, status); 235d5ac70f0Sopenharmony_ci} 236d5ac70f0Sopenharmony_ci 237d5ac70f0Sopenharmony_ci/** 238d5ac70f0Sopenharmony_ci * \brief drop all packets in the rawmidi I/O ring buffer immediately 239d5ac70f0Sopenharmony_ci * \param ump UMP handle 240d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 241d5ac70f0Sopenharmony_ci */ 242d5ac70f0Sopenharmony_ciint snd_ump_drop(snd_ump_t *ump) 243d5ac70f0Sopenharmony_ci{ 244d5ac70f0Sopenharmony_ci return snd_rawmidi_drop(ump->rawmidi); 245d5ac70f0Sopenharmony_ci} 246d5ac70f0Sopenharmony_ci 247d5ac70f0Sopenharmony_ci/** 248d5ac70f0Sopenharmony_ci * \brief drain all packets in the UMP I/O ring buffer 249d5ac70f0Sopenharmony_ci * \param ump UMP handle 250d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 251d5ac70f0Sopenharmony_ci * 252d5ac70f0Sopenharmony_ci * Waits until all MIDI packets are not drained (sent) to the 253d5ac70f0Sopenharmony_ci * hardware device. 254d5ac70f0Sopenharmony_ci */ 255d5ac70f0Sopenharmony_ciint snd_ump_drain(snd_ump_t *ump) 256d5ac70f0Sopenharmony_ci{ 257d5ac70f0Sopenharmony_ci return snd_rawmidi_drain(ump->rawmidi); 258d5ac70f0Sopenharmony_ci} 259d5ac70f0Sopenharmony_ci 260d5ac70f0Sopenharmony_ci/** 261d5ac70f0Sopenharmony_ci * \brief write UMP packets to UMP stream 262d5ac70f0Sopenharmony_ci * \param ump UMP handle 263d5ac70f0Sopenharmony_ci * \param buffer buffer containing UMP packets 264d5ac70f0Sopenharmony_ci * \param size output buffer size in bytes 265d5ac70f0Sopenharmony_ci */ 266d5ac70f0Sopenharmony_cissize_t snd_ump_write(snd_ump_t *ump, const void *buffer, size_t size) 267d5ac70f0Sopenharmony_ci{ 268d5ac70f0Sopenharmony_ci if (ump->is_input) 269d5ac70f0Sopenharmony_ci return -EINVAL; 270d5ac70f0Sopenharmony_ci return snd_rawmidi_write(ump->rawmidi, buffer, size); 271d5ac70f0Sopenharmony_ci} 272d5ac70f0Sopenharmony_ci 273d5ac70f0Sopenharmony_ci/** 274d5ac70f0Sopenharmony_ci * \brief read UMP packets from UMP stream 275d5ac70f0Sopenharmony_ci * \param ump UMP handle 276d5ac70f0Sopenharmony_ci * \param buffer buffer to store the input MIDI bytes 277d5ac70f0Sopenharmony_ci * \param size input buffer size in bytes 278d5ac70f0Sopenharmony_ci * \retval count of UMP packet in bytes otherwise a negative error code 279d5ac70f0Sopenharmony_ci */ 280d5ac70f0Sopenharmony_cissize_t snd_ump_read(snd_ump_t *ump, void *buffer, size_t size) 281d5ac70f0Sopenharmony_ci{ 282d5ac70f0Sopenharmony_ci if (!ump->is_input) 283d5ac70f0Sopenharmony_ci return -EINVAL; 284d5ac70f0Sopenharmony_ci return snd_rawmidi_read(ump->rawmidi, buffer, size); 285d5ac70f0Sopenharmony_ci} 286d5ac70f0Sopenharmony_ci 287d5ac70f0Sopenharmony_ci/** 288d5ac70f0Sopenharmony_ci * \brief read UMP packets from UMP stream with timestamp 289d5ac70f0Sopenharmony_ci * \param ump UMP handle 290d5ac70f0Sopenharmony_ci * \param[out] tstamp timestamp for the returned UMP packets 291d5ac70f0Sopenharmony_ci * \param buffer buffer to store the input UMP packets 292d5ac70f0Sopenharmony_ci * \param size input buffer size in bytes 293d5ac70f0Sopenharmony_ci * \retval count of UMP packet in bytes otherwise a negative error code 294d5ac70f0Sopenharmony_ci */ 295d5ac70f0Sopenharmony_cissize_t snd_ump_tread(snd_ump_t *ump, struct timespec *tstamp, void *buffer, 296d5ac70f0Sopenharmony_ci size_t size) 297d5ac70f0Sopenharmony_ci{ 298d5ac70f0Sopenharmony_ci if (!ump->is_input) 299d5ac70f0Sopenharmony_ci return -EINVAL; 300d5ac70f0Sopenharmony_ci return snd_rawmidi_tread(ump->rawmidi, tstamp, buffer, size); 301d5ac70f0Sopenharmony_ci} 302d5ac70f0Sopenharmony_ci 303d5ac70f0Sopenharmony_ci/** 304d5ac70f0Sopenharmony_ci * \brief get size of the snd_ump_endpoint_info_t structure in bytes 305d5ac70f0Sopenharmony_ci * \return size of the snd_ump_endpoint_info_t structure in bytes 306d5ac70f0Sopenharmony_ci */ 307d5ac70f0Sopenharmony_cisize_t snd_ump_endpoint_info_sizeof(void) 308d5ac70f0Sopenharmony_ci{ 309d5ac70f0Sopenharmony_ci return sizeof(snd_ump_endpoint_info_t); 310d5ac70f0Sopenharmony_ci} 311d5ac70f0Sopenharmony_ci 312d5ac70f0Sopenharmony_ci/** 313d5ac70f0Sopenharmony_ci * \brief allocate the snd_ump_endpoint_info_t structure 314d5ac70f0Sopenharmony_ci * \param info returned pointer 315d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code if fails 316d5ac70f0Sopenharmony_ci * 317d5ac70f0Sopenharmony_ci * Allocates a new snd_rawmidi_status_t structure using the standard 318d5ac70f0Sopenharmony_ci * malloc C library function. 319d5ac70f0Sopenharmony_ci */ 320d5ac70f0Sopenharmony_ciint snd_ump_endpoint_info_malloc(snd_ump_endpoint_info_t **info) 321d5ac70f0Sopenharmony_ci{ 322d5ac70f0Sopenharmony_ci *info = calloc(1, sizeof(snd_ump_endpoint_info_t)); 323d5ac70f0Sopenharmony_ci if (!*info) 324d5ac70f0Sopenharmony_ci return -ENOMEM; 325d5ac70f0Sopenharmony_ci return 0; 326d5ac70f0Sopenharmony_ci} 327d5ac70f0Sopenharmony_ci 328d5ac70f0Sopenharmony_ci/** 329d5ac70f0Sopenharmony_ci * \brief frees the snd_ump_endpoint_info_t structure 330d5ac70f0Sopenharmony_ci * \param info pointer to the snd_ump_endpoint_info_t structure to free 331d5ac70f0Sopenharmony_ci * 332d5ac70f0Sopenharmony_ci * Frees the given snd_ump_endpoint_info_t structure using the standard 333d5ac70f0Sopenharmony_ci * free C library function. 334d5ac70f0Sopenharmony_ci */ 335d5ac70f0Sopenharmony_civoid snd_ump_endpoint_info_free(snd_ump_endpoint_info_t *info) 336d5ac70f0Sopenharmony_ci{ 337d5ac70f0Sopenharmony_ci free(info); 338d5ac70f0Sopenharmony_ci} 339d5ac70f0Sopenharmony_ci 340d5ac70f0Sopenharmony_ci/** 341d5ac70f0Sopenharmony_ci * \brief copy one snd_ump_endpoint_info_t structure to another 342d5ac70f0Sopenharmony_ci * \param dst destination snd_ump_endpoint_info_t structure 343d5ac70f0Sopenharmony_ci * \param src source snd_ump_endpoint_info_t structure 344d5ac70f0Sopenharmony_ci */ 345d5ac70f0Sopenharmony_civoid snd_ump_endpoint_info_copy(snd_ump_endpoint_info_t *dst, 346d5ac70f0Sopenharmony_ci const snd_ump_endpoint_info_t *src) 347d5ac70f0Sopenharmony_ci{ 348d5ac70f0Sopenharmony_ci *dst = *src; 349d5ac70f0Sopenharmony_ci} 350d5ac70f0Sopenharmony_ci 351d5ac70f0Sopenharmony_ci/** 352d5ac70f0Sopenharmony_ci * \brief get card number of UMP endpoint 353d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 354d5ac70f0Sopenharmony_ci * \return the card number of the given UMP endpoint 355d5ac70f0Sopenharmony_ci */ 356d5ac70f0Sopenharmony_ciint snd_ump_endpoint_info_get_card(const snd_ump_endpoint_info_t *info) 357d5ac70f0Sopenharmony_ci{ 358d5ac70f0Sopenharmony_ci return info->card; 359d5ac70f0Sopenharmony_ci} 360d5ac70f0Sopenharmony_ci 361d5ac70f0Sopenharmony_ci/** 362d5ac70f0Sopenharmony_ci * \brief get device number of UMP endpoint 363d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 364d5ac70f0Sopenharmony_ci * \return the device number of the given UMP endpoint 365d5ac70f0Sopenharmony_ci */ 366d5ac70f0Sopenharmony_ciint snd_ump_endpoint_info_get_device(const snd_ump_endpoint_info_t *info) 367d5ac70f0Sopenharmony_ci{ 368d5ac70f0Sopenharmony_ci return info->device; 369d5ac70f0Sopenharmony_ci} 370d5ac70f0Sopenharmony_ci 371d5ac70f0Sopenharmony_ci/** 372d5ac70f0Sopenharmony_ci * \brief get UMP endpoint info flags 373d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 374d5ac70f0Sopenharmony_ci * \return UMP endpoint flag bits 375d5ac70f0Sopenharmony_ci */ 376d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_flags(const snd_ump_endpoint_info_t *info) 377d5ac70f0Sopenharmony_ci{ 378d5ac70f0Sopenharmony_ci return info->flags; 379d5ac70f0Sopenharmony_ci} 380d5ac70f0Sopenharmony_ci 381d5ac70f0Sopenharmony_ci/** 382d5ac70f0Sopenharmony_ci * \brief get UMP endpoint protocol capability bits 383d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 384d5ac70f0Sopenharmony_ci * \return UMP endpoint protocol capability bits 385d5ac70f0Sopenharmony_ci */ 386d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_protocol_caps(const snd_ump_endpoint_info_t *info) 387d5ac70f0Sopenharmony_ci{ 388d5ac70f0Sopenharmony_ci return info->protocol_caps; 389d5ac70f0Sopenharmony_ci} 390d5ac70f0Sopenharmony_ci 391d5ac70f0Sopenharmony_ci/** 392d5ac70f0Sopenharmony_ci * \brief get the current UMP endpoint protocol 393d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 394d5ac70f0Sopenharmony_ci * \return UMP endpoint protocol bits 395d5ac70f0Sopenharmony_ci */ 396d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_protocol(const snd_ump_endpoint_info_t *info) 397d5ac70f0Sopenharmony_ci{ 398d5ac70f0Sopenharmony_ci return info->protocol; 399d5ac70f0Sopenharmony_ci} 400d5ac70f0Sopenharmony_ci 401d5ac70f0Sopenharmony_ci/** 402d5ac70f0Sopenharmony_ci * \brief get the number of UMP blocks belonging to the endpoint 403d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 404d5ac70f0Sopenharmony_ci * \return number of UMP blocks 405d5ac70f0Sopenharmony_ci */ 406d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_num_blocks(const snd_ump_endpoint_info_t *info) 407d5ac70f0Sopenharmony_ci{ 408d5ac70f0Sopenharmony_ci return info->num_blocks; 409d5ac70f0Sopenharmony_ci} 410d5ac70f0Sopenharmony_ci 411d5ac70f0Sopenharmony_ci/** 412d5ac70f0Sopenharmony_ci * \brief get UMP version number 413d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 414d5ac70f0Sopenharmony_ci * \return UMP version number 415d5ac70f0Sopenharmony_ci */ 416d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_version(const snd_ump_endpoint_info_t *info) 417d5ac70f0Sopenharmony_ci{ 418d5ac70f0Sopenharmony_ci return info->version; 419d5ac70f0Sopenharmony_ci} 420d5ac70f0Sopenharmony_ci 421d5ac70f0Sopenharmony_ci/** 422d5ac70f0Sopenharmony_ci * \brief get UMP manufacturer ID 423d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 424d5ac70f0Sopenharmony_ci * \return UMP manufacturer ID 425d5ac70f0Sopenharmony_ci */ 426d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_manufacturer_id(const snd_ump_endpoint_info_t *info) 427d5ac70f0Sopenharmony_ci{ 428d5ac70f0Sopenharmony_ci return info->manufacturer_id; 429d5ac70f0Sopenharmony_ci} 430d5ac70f0Sopenharmony_ci 431d5ac70f0Sopenharmony_ci/** 432d5ac70f0Sopenharmony_ci * \brief get UMP family ID 433d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 434d5ac70f0Sopenharmony_ci * \return UMP family ID 435d5ac70f0Sopenharmony_ci */ 436d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_family_id(const snd_ump_endpoint_info_t *info) 437d5ac70f0Sopenharmony_ci{ 438d5ac70f0Sopenharmony_ci return info->family_id; 439d5ac70f0Sopenharmony_ci} 440d5ac70f0Sopenharmony_ci 441d5ac70f0Sopenharmony_ci/** 442d5ac70f0Sopenharmony_ci * \brief get UMP model ID 443d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 444d5ac70f0Sopenharmony_ci * \return UMP model ID 445d5ac70f0Sopenharmony_ci */ 446d5ac70f0Sopenharmony_ciunsigned int snd_ump_endpoint_info_get_model_id(const snd_ump_endpoint_info_t *info) 447d5ac70f0Sopenharmony_ci{ 448d5ac70f0Sopenharmony_ci return info->model_id; 449d5ac70f0Sopenharmony_ci} 450d5ac70f0Sopenharmony_ci 451d5ac70f0Sopenharmony_ci/** 452d5ac70f0Sopenharmony_ci * \brief get UMP software revision 453d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 454d5ac70f0Sopenharmony_ci * \return UMP software revision 455d5ac70f0Sopenharmony_ci */ 456d5ac70f0Sopenharmony_ciconst unsigned char *snd_ump_endpoint_info_get_sw_revision(const snd_ump_endpoint_info_t *info) 457d5ac70f0Sopenharmony_ci{ 458d5ac70f0Sopenharmony_ci return info->sw_revision; 459d5ac70f0Sopenharmony_ci} 460d5ac70f0Sopenharmony_ci 461d5ac70f0Sopenharmony_ci/** 462d5ac70f0Sopenharmony_ci * \brief get UMP endpoint name string 463d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 464d5ac70f0Sopenharmony_ci * \return UMP endpoint name string 465d5ac70f0Sopenharmony_ci */ 466d5ac70f0Sopenharmony_ciconst char *snd_ump_endpoint_info_get_name(const snd_ump_endpoint_info_t *info) 467d5ac70f0Sopenharmony_ci{ 468d5ac70f0Sopenharmony_ci return (const char *)info->name; 469d5ac70f0Sopenharmony_ci} 470d5ac70f0Sopenharmony_ci 471d5ac70f0Sopenharmony_ci/** 472d5ac70f0Sopenharmony_ci * \brief get UMP endpoint product ID string 473d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure 474d5ac70f0Sopenharmony_ci * \return UMP endpoint product ID string 475d5ac70f0Sopenharmony_ci */ 476d5ac70f0Sopenharmony_ciconst char *snd_ump_endpoint_info_get_product_id(const snd_ump_endpoint_info_t *info) 477d5ac70f0Sopenharmony_ci{ 478d5ac70f0Sopenharmony_ci return (const char *)info->product_id; 479d5ac70f0Sopenharmony_ci} 480d5ac70f0Sopenharmony_ci 481d5ac70f0Sopenharmony_ci/** 482d5ac70f0Sopenharmony_ci * \brief get endpoint information about UMP handle 483d5ac70f0Sopenharmony_ci * \param ump UMP handle 484d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_endpoint_info_t structure to be filled 485d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 486d5ac70f0Sopenharmony_ci */ 487d5ac70f0Sopenharmony_ciint snd_ump_endpoint_info(snd_ump_t *ump, snd_ump_endpoint_info_t *info) 488d5ac70f0Sopenharmony_ci{ 489d5ac70f0Sopenharmony_ci return _snd_rawmidi_ump_endpoint_info(ump->rawmidi, info); 490d5ac70f0Sopenharmony_ci} 491d5ac70f0Sopenharmony_ci 492d5ac70f0Sopenharmony_ci/** 493d5ac70f0Sopenharmony_ci * \brief get size of the snd_ump_block_info_t structure in bytes 494d5ac70f0Sopenharmony_ci * \return size of the snd_ump_block_info_t structure in bytes 495d5ac70f0Sopenharmony_ci */ 496d5ac70f0Sopenharmony_cisize_t snd_ump_block_info_sizeof(void) 497d5ac70f0Sopenharmony_ci{ 498d5ac70f0Sopenharmony_ci return sizeof(snd_ump_block_info_t); 499d5ac70f0Sopenharmony_ci} 500d5ac70f0Sopenharmony_ci 501d5ac70f0Sopenharmony_ci/** 502d5ac70f0Sopenharmony_ci * \brief allocate the snd_ump_block_info_t structure 503d5ac70f0Sopenharmony_ci * \param info returned pointer 504d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code if fails 505d5ac70f0Sopenharmony_ci * 506d5ac70f0Sopenharmony_ci * Allocates a new snd_ump_block_info_t structure using the standard 507d5ac70f0Sopenharmony_ci * malloc C library function. 508d5ac70f0Sopenharmony_ci */ 509d5ac70f0Sopenharmony_ciint snd_ump_block_info_malloc(snd_ump_block_info_t **info) 510d5ac70f0Sopenharmony_ci{ 511d5ac70f0Sopenharmony_ci *info = calloc(1, sizeof(snd_ump_block_info_t)); 512d5ac70f0Sopenharmony_ci if (!*info) 513d5ac70f0Sopenharmony_ci return -ENOMEM; 514d5ac70f0Sopenharmony_ci return 0; 515d5ac70f0Sopenharmony_ci} 516d5ac70f0Sopenharmony_ci 517d5ac70f0Sopenharmony_ci/** 518d5ac70f0Sopenharmony_ci * \brief frees the snd_ump_block_info_t structure 519d5ac70f0Sopenharmony_ci * \param info pointer to the snd_ump_block_info_t structure to free 520d5ac70f0Sopenharmony_ci * 521d5ac70f0Sopenharmony_ci * Frees the given snd_ump_block_info_t structure using the standard 522d5ac70f0Sopenharmony_ci * free C library function. 523d5ac70f0Sopenharmony_ci */ 524d5ac70f0Sopenharmony_civoid snd_ump_block_info_free(snd_ump_block_info_t *info) 525d5ac70f0Sopenharmony_ci{ 526d5ac70f0Sopenharmony_ci free(info); 527d5ac70f0Sopenharmony_ci} 528d5ac70f0Sopenharmony_ci 529d5ac70f0Sopenharmony_ci/** 530d5ac70f0Sopenharmony_ci * \brief copy one snd_ump_block_info_t structure to another 531d5ac70f0Sopenharmony_ci * \param dst destination snd_ump_block_info_t structure 532d5ac70f0Sopenharmony_ci * \param src source snd_ump_block_info_t structure 533d5ac70f0Sopenharmony_ci */ 534d5ac70f0Sopenharmony_civoid snd_ump_block_info_copy(snd_ump_block_info_t *dst, 535d5ac70f0Sopenharmony_ci const snd_ump_block_info_t *src) 536d5ac70f0Sopenharmony_ci{ 537d5ac70f0Sopenharmony_ci *dst = *src; 538d5ac70f0Sopenharmony_ci} 539d5ac70f0Sopenharmony_ci 540d5ac70f0Sopenharmony_ci/** 541d5ac70f0Sopenharmony_ci * \brief get card number of UMP block 542d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 543d5ac70f0Sopenharmony_ci * \return the card number of the given UMP block 544d5ac70f0Sopenharmony_ci */ 545d5ac70f0Sopenharmony_ciint snd_ump_block_info_get_card(const snd_ump_block_info_t *info) 546d5ac70f0Sopenharmony_ci{ 547d5ac70f0Sopenharmony_ci return info->card; 548d5ac70f0Sopenharmony_ci} 549d5ac70f0Sopenharmony_ci 550d5ac70f0Sopenharmony_ci/** 551d5ac70f0Sopenharmony_ci * \brief get device number of UMP block 552d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 553d5ac70f0Sopenharmony_ci * \return the device number of the given UMP block 554d5ac70f0Sopenharmony_ci */ 555d5ac70f0Sopenharmony_ciint snd_ump_block_info_get_device(const snd_ump_block_info_t *info) 556d5ac70f0Sopenharmony_ci{ 557d5ac70f0Sopenharmony_ci return info->device; 558d5ac70f0Sopenharmony_ci} 559d5ac70f0Sopenharmony_ci 560d5ac70f0Sopenharmony_ci/** 561d5ac70f0Sopenharmony_ci * \brief get UMP block ID 562d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 563d5ac70f0Sopenharmony_ci * \return ID number of the given UMP block 564d5ac70f0Sopenharmony_ci */ 565d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_block_id(const snd_ump_block_info_t *info) 566d5ac70f0Sopenharmony_ci{ 567d5ac70f0Sopenharmony_ci return info->block_id; 568d5ac70f0Sopenharmony_ci} 569d5ac70f0Sopenharmony_ci 570d5ac70f0Sopenharmony_ci/** 571d5ac70f0Sopenharmony_ci * \brief set UMP block ID for query 572d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 573d5ac70f0Sopenharmony_ci * \param id the ID number for query 574d5ac70f0Sopenharmony_ci */ 575d5ac70f0Sopenharmony_civoid snd_ump_block_info_set_block_id(snd_ump_block_info_t *info, 576d5ac70f0Sopenharmony_ci unsigned int id) 577d5ac70f0Sopenharmony_ci{ 578d5ac70f0Sopenharmony_ci info->block_id = id; 579d5ac70f0Sopenharmony_ci} 580d5ac70f0Sopenharmony_ci 581d5ac70f0Sopenharmony_ci/** 582d5ac70f0Sopenharmony_ci * \brief get UMP block activeness 583d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 584d5ac70f0Sopenharmony_ci * \return 1 if the block is active or 0 if inactive 585d5ac70f0Sopenharmony_ci */ 586d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_active(const snd_ump_block_info_t *info) 587d5ac70f0Sopenharmony_ci{ 588d5ac70f0Sopenharmony_ci return info->active; 589d5ac70f0Sopenharmony_ci} 590d5ac70f0Sopenharmony_ci 591d5ac70f0Sopenharmony_ci/** 592d5ac70f0Sopenharmony_ci * \brief get UMP block information flags 593d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 594d5ac70f0Sopenharmony_ci * \return info flag bits for the given UMP block 595d5ac70f0Sopenharmony_ci */ 596d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_flags(const snd_ump_block_info_t *info) 597d5ac70f0Sopenharmony_ci{ 598d5ac70f0Sopenharmony_ci return info->flags; 599d5ac70f0Sopenharmony_ci} 600d5ac70f0Sopenharmony_ci 601d5ac70f0Sopenharmony_ci/** 602d5ac70f0Sopenharmony_ci * \brief get UMP block direction 603d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 604d5ac70f0Sopenharmony_ci * \return direction of UMP block (input,output,bidirectional) 605d5ac70f0Sopenharmony_ci */ 606d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_direction(const snd_ump_block_info_t *info) 607d5ac70f0Sopenharmony_ci{ 608d5ac70f0Sopenharmony_ci return info->direction; 609d5ac70f0Sopenharmony_ci} 610d5ac70f0Sopenharmony_ci 611d5ac70f0Sopenharmony_ci/** 612d5ac70f0Sopenharmony_ci * \brief get first UMP group ID belonging to the block 613d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 614d5ac70f0Sopenharmony_ci * \return the first UMP group ID belonging to the block 615d5ac70f0Sopenharmony_ci */ 616d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_first_group(const snd_ump_block_info_t *info) 617d5ac70f0Sopenharmony_ci{ 618d5ac70f0Sopenharmony_ci return info->first_group; 619d5ac70f0Sopenharmony_ci} 620d5ac70f0Sopenharmony_ci 621d5ac70f0Sopenharmony_ci/** 622d5ac70f0Sopenharmony_ci * \brief get number of UMP groups belonging to the block 623d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 624d5ac70f0Sopenharmony_ci * \return the number of UMP groups belonging to the block 625d5ac70f0Sopenharmony_ci */ 626d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_num_groups(const snd_ump_block_info_t *info) 627d5ac70f0Sopenharmony_ci{ 628d5ac70f0Sopenharmony_ci return info->num_groups; 629d5ac70f0Sopenharmony_ci} 630d5ac70f0Sopenharmony_ci 631d5ac70f0Sopenharmony_ci/** 632d5ac70f0Sopenharmony_ci * \brief get MIDI-CI version number 633d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 634d5ac70f0Sopenharmony_ci * \return MIDI-CI version number 635d5ac70f0Sopenharmony_ci */ 636d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_midi_ci_version(const snd_ump_block_info_t *info) 637d5ac70f0Sopenharmony_ci{ 638d5ac70f0Sopenharmony_ci return info->midi_ci_version; 639d5ac70f0Sopenharmony_ci} 640d5ac70f0Sopenharmony_ci 641d5ac70f0Sopenharmony_ci/** 642d5ac70f0Sopenharmony_ci * \brief get number of supported SysEx8 streams 643d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 644d5ac70f0Sopenharmony_ci * \return number of supported SysEx8 streams 645d5ac70f0Sopenharmony_ci */ 646d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_sysex8_streams(const snd_ump_block_info_t *info) 647d5ac70f0Sopenharmony_ci{ 648d5ac70f0Sopenharmony_ci return info->sysex8_streams; 649d5ac70f0Sopenharmony_ci} 650d5ac70f0Sopenharmony_ci 651d5ac70f0Sopenharmony_ci/** 652d5ac70f0Sopenharmony_ci * \brief get UI hint of the given UMP block 653d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 654d5ac70f0Sopenharmony_ci * \return the hint bits 655d5ac70f0Sopenharmony_ci */ 656d5ac70f0Sopenharmony_ciunsigned int snd_ump_block_info_get_ui_hint(const snd_ump_block_info_t *info) 657d5ac70f0Sopenharmony_ci{ 658d5ac70f0Sopenharmony_ci return info->ui_hint; 659d5ac70f0Sopenharmony_ci} 660d5ac70f0Sopenharmony_ci 661d5ac70f0Sopenharmony_ci/** 662d5ac70f0Sopenharmony_ci * \brief get the name string of UMP block 663d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 664d5ac70f0Sopenharmony_ci * \return the name string of UMP block 665d5ac70f0Sopenharmony_ci */ 666d5ac70f0Sopenharmony_ciconst char *snd_ump_block_info_get_name(const snd_ump_block_info_t *info) 667d5ac70f0Sopenharmony_ci{ 668d5ac70f0Sopenharmony_ci return (const char *)info->name; 669d5ac70f0Sopenharmony_ci} 670d5ac70f0Sopenharmony_ci 671d5ac70f0Sopenharmony_ci/** 672d5ac70f0Sopenharmony_ci * \brief get UMP block information 673d5ac70f0Sopenharmony_ci * \param ump UMP handle 674d5ac70f0Sopenharmony_ci * \param info pointer to a snd_ump_block_info_t structure 675d5ac70f0Sopenharmony_ci * \return 0 on success otherwise a negative error code 676d5ac70f0Sopenharmony_ci * 677d5ac70f0Sopenharmony_ci * The caller should fill the block ID to query at first via 678d5ac70f0Sopenharmony_ci * snd_ump_block_info_set_block_id(). 679d5ac70f0Sopenharmony_ci */ 680d5ac70f0Sopenharmony_ciint snd_ump_block_info(snd_ump_t *ump, snd_ump_block_info_t *info) 681d5ac70f0Sopenharmony_ci{ 682d5ac70f0Sopenharmony_ci return _snd_rawmidi_ump_block_info(ump->rawmidi, info); 683d5ac70f0Sopenharmony_ci} 684d5ac70f0Sopenharmony_ci 685d5ac70f0Sopenharmony_ci/* 686d5ac70f0Sopenharmony_ci * UMP sysex helpers 687d5ac70f0Sopenharmony_ci */ 688d5ac70f0Sopenharmony_cistatic int expand_sysex_data(const uint32_t *data, uint8_t *buf, 689d5ac70f0Sopenharmony_ci size_t maxlen, unsigned char bytes, int offset) 690d5ac70f0Sopenharmony_ci{ 691d5ac70f0Sopenharmony_ci int size = 0; 692d5ac70f0Sopenharmony_ci 693d5ac70f0Sopenharmony_ci for (; bytes; bytes--, size++) { 694d5ac70f0Sopenharmony_ci if (!maxlen) 695d5ac70f0Sopenharmony_ci break; 696d5ac70f0Sopenharmony_ci buf[size] = (*data >> offset) & 0x7f; 697d5ac70f0Sopenharmony_ci if (!offset) { 698d5ac70f0Sopenharmony_ci offset = 24; 699d5ac70f0Sopenharmony_ci data++; 700d5ac70f0Sopenharmony_ci } else { 701d5ac70f0Sopenharmony_ci offset -= 8; 702d5ac70f0Sopenharmony_ci } 703d5ac70f0Sopenharmony_ci } 704d5ac70f0Sopenharmony_ci 705d5ac70f0Sopenharmony_ci return size; 706d5ac70f0Sopenharmony_ci} 707d5ac70f0Sopenharmony_ci 708d5ac70f0Sopenharmony_cistatic int expand_sysex7(const uint32_t *ump, uint8_t *buf, size_t maxlen, 709d5ac70f0Sopenharmony_ci size_t *filled) 710d5ac70f0Sopenharmony_ci{ 711d5ac70f0Sopenharmony_ci unsigned char status; 712d5ac70f0Sopenharmony_ci unsigned char bytes; 713d5ac70f0Sopenharmony_ci 714d5ac70f0Sopenharmony_ci *filled = 0; 715d5ac70f0Sopenharmony_ci if (!maxlen) 716d5ac70f0Sopenharmony_ci return 0; 717d5ac70f0Sopenharmony_ci 718d5ac70f0Sopenharmony_ci status = snd_ump_sysex_msg_status(ump); 719d5ac70f0Sopenharmony_ci bytes = snd_ump_sysex_msg_length(ump); 720d5ac70f0Sopenharmony_ci if (bytes > 6) 721d5ac70f0Sopenharmony_ci return 0; // invalid - skip 722d5ac70f0Sopenharmony_ci 723d5ac70f0Sopenharmony_ci *filled = expand_sysex_data(ump, buf, maxlen, bytes, 8); 724d5ac70f0Sopenharmony_ci return (status == SND_UMP_SYSEX_STATUS_SINGLE || 725d5ac70f0Sopenharmony_ci status == SND_UMP_SYSEX_STATUS_END); 726d5ac70f0Sopenharmony_ci} 727d5ac70f0Sopenharmony_ci 728d5ac70f0Sopenharmony_cistatic int expand_sysex8(const uint32_t *ump, uint8_t *buf, size_t maxlen, 729d5ac70f0Sopenharmony_ci size_t *filled) 730d5ac70f0Sopenharmony_ci{ 731d5ac70f0Sopenharmony_ci unsigned char status; 732d5ac70f0Sopenharmony_ci unsigned char bytes; 733d5ac70f0Sopenharmony_ci 734d5ac70f0Sopenharmony_ci *filled = 0; 735d5ac70f0Sopenharmony_ci if (!maxlen) 736d5ac70f0Sopenharmony_ci return 0; 737d5ac70f0Sopenharmony_ci 738d5ac70f0Sopenharmony_ci status = snd_ump_sysex_msg_status(ump); 739d5ac70f0Sopenharmony_ci if (status > SND_UMP_SYSEX_STATUS_END) 740d5ac70f0Sopenharmony_ci return 0; // unsupported, skip 741d5ac70f0Sopenharmony_ci bytes = snd_ump_sysex_msg_length(ump); 742d5ac70f0Sopenharmony_ci if (!bytes || bytes > 14) 743d5ac70f0Sopenharmony_ci return 0; // skip 744d5ac70f0Sopenharmony_ci 745d5ac70f0Sopenharmony_ci *filled = expand_sysex_data(ump, buf, maxlen, bytes - 1, 0); 746d5ac70f0Sopenharmony_ci return (status == SND_UMP_SYSEX_STATUS_SINGLE || 747d5ac70f0Sopenharmony_ci status == SND_UMP_SYSEX_STATUS_END); 748d5ac70f0Sopenharmony_ci} 749d5ac70f0Sopenharmony_ci 750d5ac70f0Sopenharmony_ci/** 751d5ac70f0Sopenharmony_ci * \brief fill sysex byte from a UMP packet 752d5ac70f0Sopenharmony_ci * \param ump UMP packet pointer 753d5ac70f0Sopenharmony_ci * \param buf buffer point to fill sysex bytes 754d5ac70f0Sopenharmony_ci * \param maxlen max buffer size in bytes 755d5ac70f0Sopenharmony_ci * \param filled the size of filled sysex bytes on the buffer 756d5ac70f0Sopenharmony_ci * \return 1 if the sysex finished, otherwise 0 757d5ac70f0Sopenharmony_ci */ 758d5ac70f0Sopenharmony_ciint snd_ump_msg_sysex_expand(const uint32_t *ump, uint8_t *buf, size_t maxlen, 759d5ac70f0Sopenharmony_ci size_t *filled) 760d5ac70f0Sopenharmony_ci{ 761d5ac70f0Sopenharmony_ci switch (snd_ump_msg_type(ump)) { 762d5ac70f0Sopenharmony_ci case SND_UMP_MSG_TYPE_DATA: 763d5ac70f0Sopenharmony_ci return expand_sysex7(ump, buf, maxlen, filled); 764d5ac70f0Sopenharmony_ci case SND_UMP_MSG_TYPE_EXTENDED_DATA: 765d5ac70f0Sopenharmony_ci return expand_sysex8(ump, buf, maxlen, filled); 766d5ac70f0Sopenharmony_ci default: 767d5ac70f0Sopenharmony_ci return -EINVAL; 768d5ac70f0Sopenharmony_ci } 769d5ac70f0Sopenharmony_ci} 770