1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * Sequencer Interface - middle-level routines 3d5ac70f0Sopenharmony_ci * 4d5ac70f0Sopenharmony_ci * Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de> 5d5ac70f0Sopenharmony_ci * 6d5ac70f0Sopenharmony_ci * 7d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 8d5ac70f0Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 9d5ac70f0Sopenharmony_ci * published by the Free Software Foundation; either version 2.1 of 10d5ac70f0Sopenharmony_ci * the License, or (at your option) any later version. 11d5ac70f0Sopenharmony_ci * 12d5ac70f0Sopenharmony_ci * This program is distributed in the hope that it will be useful, 13d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15d5ac70f0Sopenharmony_ci * GNU Lesser General Public License for more details. 16d5ac70f0Sopenharmony_ci * 17d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 19d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20d5ac70f0Sopenharmony_ci * 21d5ac70f0Sopenharmony_ci */ 22d5ac70f0Sopenharmony_ci 23d5ac70f0Sopenharmony_ci#include "seq_local.h" 24d5ac70f0Sopenharmony_ci#include <unistd.h> 25d5ac70f0Sopenharmony_ci#include <string.h> 26d5ac70f0Sopenharmony_ci#include <fcntl.h> 27d5ac70f0Sopenharmony_ci#include <ctype.h> 28d5ac70f0Sopenharmony_ci#include <sys/ioctl.h> 29d5ac70f0Sopenharmony_ci 30d5ac70f0Sopenharmony_ci/** 31d5ac70f0Sopenharmony_ci * \brief queue controls - start/stop/continue 32d5ac70f0Sopenharmony_ci * \param seq sequencer handle 33d5ac70f0Sopenharmony_ci * \param q queue id to control 34d5ac70f0Sopenharmony_ci * \param type event type 35d5ac70f0Sopenharmony_ci * \param value event value 36d5ac70f0Sopenharmony_ci * \param ev event instance 37d5ac70f0Sopenharmony_ci * 38d5ac70f0Sopenharmony_ci * This function sets up general queue control event and sends it. 39d5ac70f0Sopenharmony_ci * To send at scheduled time, set the schedule in \a ev. 40d5ac70f0Sopenharmony_ci * If \a ev is NULL, the event is composed locally and sent immediately 41d5ac70f0Sopenharmony_ci * to the specified queue. In any cases, you need to call #snd_seq_drain_output() 42d5ac70f0Sopenharmony_ci * appropriately to feed the event. 43d5ac70f0Sopenharmony_ci * 44d5ac70f0Sopenharmony_ci * \sa snd_seq_alloc_queue() 45d5ac70f0Sopenharmony_ci */ 46d5ac70f0Sopenharmony_ciint snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev) 47d5ac70f0Sopenharmony_ci{ 48d5ac70f0Sopenharmony_ci snd_seq_event_t tmpev; 49d5ac70f0Sopenharmony_ci if (ev == NULL) { 50d5ac70f0Sopenharmony_ci snd_seq_ev_clear(&tmpev); 51d5ac70f0Sopenharmony_ci ev = &tmpev; 52d5ac70f0Sopenharmony_ci snd_seq_ev_set_direct(ev); 53d5ac70f0Sopenharmony_ci } 54d5ac70f0Sopenharmony_ci snd_seq_ev_set_queue_control(ev, type, q, value); 55d5ac70f0Sopenharmony_ci return snd_seq_event_output(seq, ev); 56d5ac70f0Sopenharmony_ci} 57d5ac70f0Sopenharmony_ci 58d5ac70f0Sopenharmony_ci 59d5ac70f0Sopenharmony_ci/** 60d5ac70f0Sopenharmony_ci * \brief create a port - simple version 61d5ac70f0Sopenharmony_ci * \param seq sequencer handle 62d5ac70f0Sopenharmony_ci * \param name the name of the port 63d5ac70f0Sopenharmony_ci * \param caps capability bits 64d5ac70f0Sopenharmony_ci * \param type type bits 65d5ac70f0Sopenharmony_ci * \return the created port number or negative error code 66d5ac70f0Sopenharmony_ci * 67d5ac70f0Sopenharmony_ci * Creates a port with the given capability and type bits. 68d5ac70f0Sopenharmony_ci * 69d5ac70f0Sopenharmony_ci * \sa snd_seq_create_port(), snd_seq_delete_simple_port() 70d5ac70f0Sopenharmony_ci */ 71d5ac70f0Sopenharmony_ciint snd_seq_create_simple_port(snd_seq_t *seq, const char *name, 72d5ac70f0Sopenharmony_ci unsigned int caps, unsigned int type) 73d5ac70f0Sopenharmony_ci{ 74d5ac70f0Sopenharmony_ci snd_seq_port_info_t pinfo; 75d5ac70f0Sopenharmony_ci int result; 76d5ac70f0Sopenharmony_ci 77d5ac70f0Sopenharmony_ci memset(&pinfo, 0, sizeof(pinfo)); 78d5ac70f0Sopenharmony_ci if (name) 79d5ac70f0Sopenharmony_ci strncpy(pinfo.name, name, sizeof(pinfo.name) - 1); 80d5ac70f0Sopenharmony_ci pinfo.capability = caps; 81d5ac70f0Sopenharmony_ci pinfo.type = type; 82d5ac70f0Sopenharmony_ci pinfo.midi_channels = 16; 83d5ac70f0Sopenharmony_ci pinfo.midi_voices = 64; /* XXX */ 84d5ac70f0Sopenharmony_ci pinfo.synth_voices = 0; /* XXX */ 85d5ac70f0Sopenharmony_ci 86d5ac70f0Sopenharmony_ci result = snd_seq_create_port(seq, &pinfo); 87d5ac70f0Sopenharmony_ci if (result < 0) 88d5ac70f0Sopenharmony_ci return result; 89d5ac70f0Sopenharmony_ci else 90d5ac70f0Sopenharmony_ci return pinfo.addr.port; 91d5ac70f0Sopenharmony_ci} 92d5ac70f0Sopenharmony_ci 93d5ac70f0Sopenharmony_ci/** 94d5ac70f0Sopenharmony_ci * \brief delete the port 95d5ac70f0Sopenharmony_ci * \param seq sequencer handle 96d5ac70f0Sopenharmony_ci * \param port port id 97d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 98d5ac70f0Sopenharmony_ci * 99d5ac70f0Sopenharmony_ci * \sa snd_seq_delete_port(), snd_seq_create_simple_port() 100d5ac70f0Sopenharmony_ci */ 101d5ac70f0Sopenharmony_ciint snd_seq_delete_simple_port(snd_seq_t *seq, int port) 102d5ac70f0Sopenharmony_ci{ 103d5ac70f0Sopenharmony_ci return snd_seq_delete_port(seq, port); 104d5ac70f0Sopenharmony_ci} 105d5ac70f0Sopenharmony_ci 106d5ac70f0Sopenharmony_ci/** 107d5ac70f0Sopenharmony_ci * \brief simple subscription (w/o exclusive & time conversion) 108d5ac70f0Sopenharmony_ci * \param seq sequencer handle 109d5ac70f0Sopenharmony_ci * \param myport the port id as receiver 110d5ac70f0Sopenharmony_ci * \param src_client sender client id 111d5ac70f0Sopenharmony_ci * \param src_port sender port id 112d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 113d5ac70f0Sopenharmony_ci * 114d5ac70f0Sopenharmony_ci * Connect from the given sender client:port to the given destination port in the 115d5ac70f0Sopenharmony_ci * current client. 116d5ac70f0Sopenharmony_ci * 117d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from() 118d5ac70f0Sopenharmony_ci */ 119d5ac70f0Sopenharmony_ciint snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_port) 120d5ac70f0Sopenharmony_ci{ 121d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_t subs; 122d5ac70f0Sopenharmony_ci 123d5ac70f0Sopenharmony_ci memset(&subs, 0, sizeof(subs)); 124d5ac70f0Sopenharmony_ci subs.sender.client = src_client; 125d5ac70f0Sopenharmony_ci subs.sender.port = src_port; 126d5ac70f0Sopenharmony_ci /*subs.dest.client = seq->client;*/ 127d5ac70f0Sopenharmony_ci subs.dest.client = snd_seq_client_id(seq); 128d5ac70f0Sopenharmony_ci subs.dest.port = myport; 129d5ac70f0Sopenharmony_ci 130d5ac70f0Sopenharmony_ci return snd_seq_subscribe_port(seq, &subs); 131d5ac70f0Sopenharmony_ci} 132d5ac70f0Sopenharmony_ci 133d5ac70f0Sopenharmony_ci/** 134d5ac70f0Sopenharmony_ci * \brief simple subscription (w/o exclusive & time conversion) 135d5ac70f0Sopenharmony_ci * \param seq sequencer handle 136d5ac70f0Sopenharmony_ci * \param myport the port id as sender 137d5ac70f0Sopenharmony_ci * \param dest_client destination client id 138d5ac70f0Sopenharmony_ci * \param dest_port destination port id 139d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 140d5ac70f0Sopenharmony_ci * 141d5ac70f0Sopenharmony_ci * Connect from the given receiver port in the current client 142d5ac70f0Sopenharmony_ci * to the given destination client:port. 143d5ac70f0Sopenharmony_ci * 144d5ac70f0Sopenharmony_ci * \sa snd_seq_subscribe_port(), snd_seq_disconnect_to() 145d5ac70f0Sopenharmony_ci */ 146d5ac70f0Sopenharmony_ciint snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port) 147d5ac70f0Sopenharmony_ci{ 148d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_t subs; 149d5ac70f0Sopenharmony_ci 150d5ac70f0Sopenharmony_ci memset(&subs, 0, sizeof(subs)); 151d5ac70f0Sopenharmony_ci /*subs.sender.client = seq->client;*/ 152d5ac70f0Sopenharmony_ci subs.sender.client = snd_seq_client_id(seq); 153d5ac70f0Sopenharmony_ci subs.sender.port = myport; 154d5ac70f0Sopenharmony_ci subs.dest.client = dest_client; 155d5ac70f0Sopenharmony_ci subs.dest.port = dest_port; 156d5ac70f0Sopenharmony_ci 157d5ac70f0Sopenharmony_ci return snd_seq_subscribe_port(seq, &subs); 158d5ac70f0Sopenharmony_ci} 159d5ac70f0Sopenharmony_ci 160d5ac70f0Sopenharmony_ci/** 161d5ac70f0Sopenharmony_ci * \brief simple disconnection 162d5ac70f0Sopenharmony_ci * \param seq sequencer handle 163d5ac70f0Sopenharmony_ci * \param myport the port id as receiver 164d5ac70f0Sopenharmony_ci * \param src_client sender client id 165d5ac70f0Sopenharmony_ci * \param src_port sender port id 166d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 167d5ac70f0Sopenharmony_ci * 168d5ac70f0Sopenharmony_ci * Remove connection from the given sender client:port 169d5ac70f0Sopenharmony_ci * to the given destination port in the current client. 170d5ac70f0Sopenharmony_ci * 171d5ac70f0Sopenharmony_ci * \sa snd_seq_unsubscribe_port(), snd_seq_connect_from() 172d5ac70f0Sopenharmony_ci */ 173d5ac70f0Sopenharmony_ciint snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_port) 174d5ac70f0Sopenharmony_ci{ 175d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_t subs; 176d5ac70f0Sopenharmony_ci 177d5ac70f0Sopenharmony_ci memset(&subs, 0, sizeof(subs)); 178d5ac70f0Sopenharmony_ci subs.sender.client = src_client; 179d5ac70f0Sopenharmony_ci subs.sender.port = src_port; 180d5ac70f0Sopenharmony_ci /*subs.dest.client = seq->client;*/ 181d5ac70f0Sopenharmony_ci subs.dest.client = snd_seq_client_id(seq); 182d5ac70f0Sopenharmony_ci subs.dest.port = myport; 183d5ac70f0Sopenharmony_ci 184d5ac70f0Sopenharmony_ci return snd_seq_unsubscribe_port(seq, &subs); 185d5ac70f0Sopenharmony_ci} 186d5ac70f0Sopenharmony_ci 187d5ac70f0Sopenharmony_ci/** 188d5ac70f0Sopenharmony_ci * \brief simple disconnection 189d5ac70f0Sopenharmony_ci * \param seq sequencer handle 190d5ac70f0Sopenharmony_ci * \param myport the port id as sender 191d5ac70f0Sopenharmony_ci * \param dest_client destination client id 192d5ac70f0Sopenharmony_ci * \param dest_port destination port id 193d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 194d5ac70f0Sopenharmony_ci * 195d5ac70f0Sopenharmony_ci * Remove connection from the given sender client:port 196d5ac70f0Sopenharmony_ci * to the given destination port in the current client. 197d5ac70f0Sopenharmony_ci * 198d5ac70f0Sopenharmony_ci * \sa snd_seq_unsubscribe_port(), snd_seq_connect_to() 199d5ac70f0Sopenharmony_ci */ 200d5ac70f0Sopenharmony_ciint snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port) 201d5ac70f0Sopenharmony_ci{ 202d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_t subs; 203d5ac70f0Sopenharmony_ci 204d5ac70f0Sopenharmony_ci memset(&subs, 0, sizeof(subs)); 205d5ac70f0Sopenharmony_ci /*subs.sender.client = seq->client;*/ 206d5ac70f0Sopenharmony_ci subs.sender.client = snd_seq_client_id(seq); 207d5ac70f0Sopenharmony_ci subs.sender.port = myport; 208d5ac70f0Sopenharmony_ci subs.dest.client = dest_client; 209d5ac70f0Sopenharmony_ci subs.dest.port = dest_port; 210d5ac70f0Sopenharmony_ci 211d5ac70f0Sopenharmony_ci return snd_seq_unsubscribe_port(seq, &subs); 212d5ac70f0Sopenharmony_ci} 213d5ac70f0Sopenharmony_ci 214d5ac70f0Sopenharmony_ci/* 215d5ac70f0Sopenharmony_ci * set client information 216d5ac70f0Sopenharmony_ci */ 217d5ac70f0Sopenharmony_ci 218d5ac70f0Sopenharmony_ci/** 219d5ac70f0Sopenharmony_ci * \brief set client name 220d5ac70f0Sopenharmony_ci * \param seq sequencer handle 221d5ac70f0Sopenharmony_ci * \param name name string 222d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 223d5ac70f0Sopenharmony_ci * 224d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info() 225d5ac70f0Sopenharmony_ci */ 226d5ac70f0Sopenharmony_ciint snd_seq_set_client_name(snd_seq_t *seq, const char *name) 227d5ac70f0Sopenharmony_ci{ 228d5ac70f0Sopenharmony_ci snd_seq_client_info_t info; 229d5ac70f0Sopenharmony_ci int err; 230d5ac70f0Sopenharmony_ci 231d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_info(seq, &info)) < 0) 232d5ac70f0Sopenharmony_ci return err; 233d5ac70f0Sopenharmony_ci strncpy(info.name, name, sizeof(info.name) - 1); 234d5ac70f0Sopenharmony_ci return snd_seq_set_client_info(seq, &info); 235d5ac70f0Sopenharmony_ci} 236d5ac70f0Sopenharmony_ci 237d5ac70f0Sopenharmony_ci/** 238d5ac70f0Sopenharmony_ci * \brief add client event filter 239d5ac70f0Sopenharmony_ci * \param seq sequencer handle 240d5ac70f0Sopenharmony_ci * \param event_type event type to be added 241d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 242d5ac70f0Sopenharmony_ci * 243d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info() 244d5ac70f0Sopenharmony_ci */ 245d5ac70f0Sopenharmony_ciint snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type) 246d5ac70f0Sopenharmony_ci{ 247d5ac70f0Sopenharmony_ci snd_seq_client_info_t info; 248d5ac70f0Sopenharmony_ci int err; 249d5ac70f0Sopenharmony_ci 250d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_info(seq, &info)) < 0) 251d5ac70f0Sopenharmony_ci return err; 252d5ac70f0Sopenharmony_ci snd_seq_client_info_event_filter_add(&info, event_type); 253d5ac70f0Sopenharmony_ci return snd_seq_set_client_info(seq, &info); 254d5ac70f0Sopenharmony_ci} 255d5ac70f0Sopenharmony_ci 256d5ac70f0Sopenharmony_ci/** 257d5ac70f0Sopenharmony_ci * \brief set client MIDI protocol version 258d5ac70f0Sopenharmony_ci * \param seq sequencer handle 259d5ac70f0Sopenharmony_ci * \param midi_version MIDI protocol version to set 260d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 261d5ac70f0Sopenharmony_ci * 262d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info() 263d5ac70f0Sopenharmony_ci */ 264d5ac70f0Sopenharmony_ciint snd_seq_set_client_midi_version(snd_seq_t *seq, int midi_version) 265d5ac70f0Sopenharmony_ci{ 266d5ac70f0Sopenharmony_ci snd_seq_client_info_t info; 267d5ac70f0Sopenharmony_ci int err; 268d5ac70f0Sopenharmony_ci 269d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_info(seq, &info)) < 0) 270d5ac70f0Sopenharmony_ci return err; 271d5ac70f0Sopenharmony_ci snd_seq_client_info_set_midi_version(&info, midi_version); 272d5ac70f0Sopenharmony_ci return snd_seq_set_client_info(seq, &info); 273d5ac70f0Sopenharmony_ci} 274d5ac70f0Sopenharmony_ci 275d5ac70f0Sopenharmony_ci/** 276d5ac70f0Sopenharmony_ci * \brief enable/disable client's automatic conversion of UMP/legacy events 277d5ac70f0Sopenharmony_ci * \param seq sequencer handle 278d5ac70f0Sopenharmony_ci * \param enable 0 or 1 to disable/enable the conversion 279d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 280d5ac70f0Sopenharmony_ci * 281d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_info() 282d5ac70f0Sopenharmony_ci */ 283d5ac70f0Sopenharmony_ciint snd_seq_set_client_ump_conversion(snd_seq_t *seq, int enable) 284d5ac70f0Sopenharmony_ci{ 285d5ac70f0Sopenharmony_ci snd_seq_client_info_t info; 286d5ac70f0Sopenharmony_ci int err; 287d5ac70f0Sopenharmony_ci 288d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_info(seq, &info)) < 0) 289d5ac70f0Sopenharmony_ci return err; 290d5ac70f0Sopenharmony_ci snd_seq_client_info_set_ump_conversion(&info, enable); 291d5ac70f0Sopenharmony_ci return snd_seq_set_client_info(seq, &info); 292d5ac70f0Sopenharmony_ci} 293d5ac70f0Sopenharmony_ci 294d5ac70f0Sopenharmony_ci/** 295d5ac70f0Sopenharmony_ci * \brief change the output pool size of the given client 296d5ac70f0Sopenharmony_ci * \param seq sequencer handle 297d5ac70f0Sopenharmony_ci * \param size output pool size 298d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 299d5ac70f0Sopenharmony_ci * 300d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_pool() 301d5ac70f0Sopenharmony_ci */ 302d5ac70f0Sopenharmony_ciint snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size) 303d5ac70f0Sopenharmony_ci{ 304d5ac70f0Sopenharmony_ci snd_seq_client_pool_t info; 305d5ac70f0Sopenharmony_ci int err; 306d5ac70f0Sopenharmony_ci 307d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_pool(seq, &info)) < 0) 308d5ac70f0Sopenharmony_ci return err; 309d5ac70f0Sopenharmony_ci info.output_pool = size; 310d5ac70f0Sopenharmony_ci return snd_seq_set_client_pool(seq, &info); 311d5ac70f0Sopenharmony_ci} 312d5ac70f0Sopenharmony_ci 313d5ac70f0Sopenharmony_ci/** 314d5ac70f0Sopenharmony_ci * \brief change the output room size of the given client 315d5ac70f0Sopenharmony_ci * \param seq sequencer handle 316d5ac70f0Sopenharmony_ci * \param size output room size 317d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 318d5ac70f0Sopenharmony_ci * 319d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_pool() 320d5ac70f0Sopenharmony_ci */ 321d5ac70f0Sopenharmony_ciint snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size) 322d5ac70f0Sopenharmony_ci{ 323d5ac70f0Sopenharmony_ci snd_seq_client_pool_t info; 324d5ac70f0Sopenharmony_ci int err; 325d5ac70f0Sopenharmony_ci 326d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_pool(seq, &info)) < 0) 327d5ac70f0Sopenharmony_ci return err; 328d5ac70f0Sopenharmony_ci info.output_room = size; 329d5ac70f0Sopenharmony_ci return snd_seq_set_client_pool(seq, &info); 330d5ac70f0Sopenharmony_ci} 331d5ac70f0Sopenharmony_ci 332d5ac70f0Sopenharmony_ci/** 333d5ac70f0Sopenharmony_ci * \brief change the input pool size of the given client 334d5ac70f0Sopenharmony_ci * \param seq sequencer handle 335d5ac70f0Sopenharmony_ci * \param size input pool size 336d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 337d5ac70f0Sopenharmony_ci * 338d5ac70f0Sopenharmony_ci * \sa snd_seq_set_client_pool() 339d5ac70f0Sopenharmony_ci */ 340d5ac70f0Sopenharmony_ciint snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size) 341d5ac70f0Sopenharmony_ci{ 342d5ac70f0Sopenharmony_ci snd_seq_client_pool_t info; 343d5ac70f0Sopenharmony_ci int err; 344d5ac70f0Sopenharmony_ci 345d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_pool(seq, &info)) < 0) 346d5ac70f0Sopenharmony_ci return err; 347d5ac70f0Sopenharmony_ci info.input_pool = size; 348d5ac70f0Sopenharmony_ci return snd_seq_set_client_pool(seq, &info); 349d5ac70f0Sopenharmony_ci} 350d5ac70f0Sopenharmony_ci 351d5ac70f0Sopenharmony_ci/** 352d5ac70f0Sopenharmony_ci * \brief reset client output pool 353d5ac70f0Sopenharmony_ci * \param seq sequencer handle 354d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 355d5ac70f0Sopenharmony_ci * 356d5ac70f0Sopenharmony_ci * So far, this works identically like #snd_seq_drop_output(). 357d5ac70f0Sopenharmony_ci */ 358d5ac70f0Sopenharmony_ciint snd_seq_reset_pool_output(snd_seq_t *seq) 359d5ac70f0Sopenharmony_ci{ 360d5ac70f0Sopenharmony_ci return snd_seq_drop_output(seq); 361d5ac70f0Sopenharmony_ci} 362d5ac70f0Sopenharmony_ci 363d5ac70f0Sopenharmony_ci/** 364d5ac70f0Sopenharmony_ci * \brief reset client input pool 365d5ac70f0Sopenharmony_ci * \param seq sequencer handle 366d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 367d5ac70f0Sopenharmony_ci * 368d5ac70f0Sopenharmony_ci * So far, this works identically like #snd_seq_drop_input(). 369d5ac70f0Sopenharmony_ci */ 370d5ac70f0Sopenharmony_ciint snd_seq_reset_pool_input(snd_seq_t *seq) 371d5ac70f0Sopenharmony_ci{ 372d5ac70f0Sopenharmony_ci return snd_seq_drop_input(seq); 373d5ac70f0Sopenharmony_ci} 374d5ac70f0Sopenharmony_ci 375d5ac70f0Sopenharmony_ci/** 376d5ac70f0Sopenharmony_ci * \brief wait until all events are processed 377d5ac70f0Sopenharmony_ci * \param seq sequencer handle 378d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 379d5ac70f0Sopenharmony_ci * 380d5ac70f0Sopenharmony_ci * This function waits until all events of this client are processed. 381d5ac70f0Sopenharmony_ci * 382d5ac70f0Sopenharmony_ci * \sa snd_seq_drain_output() 383d5ac70f0Sopenharmony_ci */ 384d5ac70f0Sopenharmony_ciint snd_seq_sync_output_queue(snd_seq_t *seq) 385d5ac70f0Sopenharmony_ci{ 386d5ac70f0Sopenharmony_ci int err; 387d5ac70f0Sopenharmony_ci snd_seq_client_pool_t info; 388d5ac70f0Sopenharmony_ci int saved_room; 389d5ac70f0Sopenharmony_ci struct pollfd pfd; 390d5ac70f0Sopenharmony_ci 391d5ac70f0Sopenharmony_ci assert(seq); 392d5ac70f0Sopenharmony_ci /* reprogram the room size to full */ 393d5ac70f0Sopenharmony_ci if ((err = snd_seq_get_client_pool(seq, &info)) < 0) 394d5ac70f0Sopenharmony_ci return err; 395d5ac70f0Sopenharmony_ci saved_room = info.output_room; 396d5ac70f0Sopenharmony_ci info.output_room = info.output_pool; /* wait until all gone */ 397d5ac70f0Sopenharmony_ci if ((err = snd_seq_set_client_pool(seq, &info)) < 0) 398d5ac70f0Sopenharmony_ci return err; 399d5ac70f0Sopenharmony_ci /* wait until all events are purged */ 400d5ac70f0Sopenharmony_ci pfd.fd = seq->poll_fd; 401d5ac70f0Sopenharmony_ci pfd.events = POLLOUT; 402d5ac70f0Sopenharmony_ci err = poll(&pfd, 1, -1); 403d5ac70f0Sopenharmony_ci /* restore the room size */ 404d5ac70f0Sopenharmony_ci info.output_room = saved_room; 405d5ac70f0Sopenharmony_ci snd_seq_set_client_pool(seq, &info); 406d5ac70f0Sopenharmony_ci return err; 407d5ac70f0Sopenharmony_ci} 408d5ac70f0Sopenharmony_ci 409d5ac70f0Sopenharmony_ci/** 410d5ac70f0Sopenharmony_ci * \brief parse the given string and get the sequencer address 411d5ac70f0Sopenharmony_ci * \param seq sequencer handle 412d5ac70f0Sopenharmony_ci * \param addr the address pointer to be returned 413d5ac70f0Sopenharmony_ci * \param arg the string to be parsed 414d5ac70f0Sopenharmony_ci * \return 0 on success or negative error code 415d5ac70f0Sopenharmony_ci * 416d5ac70f0Sopenharmony_ci * This function parses the sequencer client and port numbers from the given string. 417d5ac70f0Sopenharmony_ci * The client and port tokens are separated by either colon or period, e.g. 128:1. 418d5ac70f0Sopenharmony_ci * When \a seq is not NULL, the function accepts also a client name not only 419d5ac70f0Sopenharmony_ci * digit numbers. 420d5ac70f0Sopenharmony_ci * Actually \a arg need to be only a prefix of the wanted client. 421d5ac70f0Sopenharmony_ci * That is, if a client named "Foobar XXL Master 2012" with number 128 is available, 422d5ac70f0Sopenharmony_ci * then parsing "Foobar" will return the address 128:0 if no other client is 423d5ac70f0Sopenharmony_ci * an exact match. 424d5ac70f0Sopenharmony_ci */ 425d5ac70f0Sopenharmony_ciint snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg) 426d5ac70f0Sopenharmony_ci{ 427d5ac70f0Sopenharmony_ci char *p, *buf; 428d5ac70f0Sopenharmony_ci const char *s; 429d5ac70f0Sopenharmony_ci char c; 430d5ac70f0Sopenharmony_ci long client, port = 0; 431d5ac70f0Sopenharmony_ci int len; 432d5ac70f0Sopenharmony_ci 433d5ac70f0Sopenharmony_ci assert(addr && arg); 434d5ac70f0Sopenharmony_ci 435d5ac70f0Sopenharmony_ci c = *arg; 436d5ac70f0Sopenharmony_ci if (c == '"' || c == '\'') { 437d5ac70f0Sopenharmony_ci s = ++arg; 438d5ac70f0Sopenharmony_ci while (*s && *s != c) s++; 439d5ac70f0Sopenharmony_ci len = s - arg; 440d5ac70f0Sopenharmony_ci if (*s) 441d5ac70f0Sopenharmony_ci s++; 442d5ac70f0Sopenharmony_ci if (*s) { 443d5ac70f0Sopenharmony_ci if (*s != '.' && *s != ':') 444d5ac70f0Sopenharmony_ci return -EINVAL; 445d5ac70f0Sopenharmony_ci if ((port = atoi(s + 1)) < 0) 446d5ac70f0Sopenharmony_ci return -EINVAL; 447d5ac70f0Sopenharmony_ci } 448d5ac70f0Sopenharmony_ci } else { 449d5ac70f0Sopenharmony_ci if ((p = strpbrk(arg, ":.")) != NULL) { 450d5ac70f0Sopenharmony_ci if ((port = atoi(p + 1)) < 0) 451d5ac70f0Sopenharmony_ci return -EINVAL; 452d5ac70f0Sopenharmony_ci len = (int)(p - arg); /* length of client name */ 453d5ac70f0Sopenharmony_ci } else { 454d5ac70f0Sopenharmony_ci len = strlen(arg); 455d5ac70f0Sopenharmony_ci } 456d5ac70f0Sopenharmony_ci } 457d5ac70f0Sopenharmony_ci if (len == 0) 458d5ac70f0Sopenharmony_ci return -EINVAL; 459d5ac70f0Sopenharmony_ci buf = alloca(len + 1); 460d5ac70f0Sopenharmony_ci strncpy(buf, arg, len); 461d5ac70f0Sopenharmony_ci buf[len] = '\0'; 462d5ac70f0Sopenharmony_ci addr->port = port; 463d5ac70f0Sopenharmony_ci if (safe_strtol(buf, &client) == 0) { 464d5ac70f0Sopenharmony_ci addr->client = client; 465d5ac70f0Sopenharmony_ci } else { 466d5ac70f0Sopenharmony_ci /* convert from the name */ 467d5ac70f0Sopenharmony_ci snd_seq_client_info_t cinfo; 468d5ac70f0Sopenharmony_ci 469d5ac70f0Sopenharmony_ci if (! seq) 470d5ac70f0Sopenharmony_ci return -EINVAL; 471d5ac70f0Sopenharmony_ci if (len <= 0) 472d5ac70f0Sopenharmony_ci return -EINVAL; 473d5ac70f0Sopenharmony_ci client = -1; 474d5ac70f0Sopenharmony_ci cinfo.client = -1; 475d5ac70f0Sopenharmony_ci while (snd_seq_query_next_client(seq, &cinfo) >= 0) { 476d5ac70f0Sopenharmony_ci if (!strncmp(arg, cinfo.name, len)) { 477d5ac70f0Sopenharmony_ci if (strlen(cinfo.name) == (size_t)len) { 478d5ac70f0Sopenharmony_ci /* exact match */ 479d5ac70f0Sopenharmony_ci addr->client = cinfo.client; 480d5ac70f0Sopenharmony_ci return 0; 481d5ac70f0Sopenharmony_ci } 482d5ac70f0Sopenharmony_ci if (client < 0) 483d5ac70f0Sopenharmony_ci client = cinfo.client; 484d5ac70f0Sopenharmony_ci } 485d5ac70f0Sopenharmony_ci } 486d5ac70f0Sopenharmony_ci if (client >= 0) { 487d5ac70f0Sopenharmony_ci /* prefix match */ 488d5ac70f0Sopenharmony_ci addr->client = client; 489d5ac70f0Sopenharmony_ci return 0; 490d5ac70f0Sopenharmony_ci } 491d5ac70f0Sopenharmony_ci return -ENOENT; /* not found */ 492d5ac70f0Sopenharmony_ci } 493d5ac70f0Sopenharmony_ci return 0; 494d5ac70f0Sopenharmony_ci} 495d5ac70f0Sopenharmony_ci 496