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