~ubuntu-branches/ubuntu/maverick/alsa-lib/maverick-proposed

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