1//------------------------------------------------------------------------------
2//
3//  EchoGals/Echo24 BeOS Driver for Echo audio cards
4//
5//	Copyright (c) 2005, Jérôme Duval
6//
7//	Permission is hereby granted, free of charge, to any person obtaining a
8//	copy of this software and associated documentation files (the "Software"),
9//	to deal in the Software without restriction, including without limitation
10//	the rights to use, copy, modify, merge, publish, distribute, sublicense,
11//	and/or sell copies of the Software, and to permit persons to whom the
12//	Software is furnished to do so, subject to the following conditions:
13//
14//	The above copyright notice and this permission notice shall be included in
15//	all copies or substantial portions of the Software.
16//
17//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22//	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23//	DEALINGS IN THE SOFTWARE.
24
25#include "echo.h"
26#include "debug.h"
27#include "midi_driver.h"
28
29static status_t midi_open(const char *name, uint32 flags, void **cookie);
30static status_t midi_close(void *cookie);
31static status_t midi_free(void *cookie);
32static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
33static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
34static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
35
36
37device_hooks midi_hooks = {
38	&midi_open,
39	&midi_close,
40	&midi_free,
41	&midi_control,
42	&midi_read,
43	&midi_write,
44	NULL,		/* select */
45	NULL,		/* deselect */
46	NULL,		/* readv */
47	NULL		/* writev */
48};
49
50static status_t
51midi_open(const char* name, uint32 flags, void** cookie)
52{
53	int ix;
54
55	LOG(("midi_open()\n"));
56
57	*cookie = NULL;
58	for (ix=0; ix<num_cards; ix++) {
59		if (!strcmp(name, cards[ix].midi.name)) {
60			break;
61		}
62	}
63	if (ix >= num_cards) {
64		LOG(("bad device\n"));
65		return ENODEV;
66	}
67
68	*cookie = &cards[ix];
69	atomic_add(&cards[ix].midi.count, 1);
70	memset(&cards[ix].midi.context, 0, sizeof(cards[ix].midi.context));
71	cards[ix].pEG->OpenMidiInput(&cards[ix].midi.context);
72	return B_OK;
73}
74
75
76static status_t
77midi_close(void* cookie)
78{
79	LOG(("midi_close()\n"));
80	return B_OK;
81}
82
83
84static status_t
85midi_free(void* cookie)
86{
87	echo_dev *card = (echo_dev *) cookie;
88
89	LOG(("midi_free()\n"));
90
91	card->pEG->CloseMidiInput(&card->midi.context);
92
93	atomic_add(&card->midi.count, -1);
94	LOG(("midi_free() done\n"));
95	return B_OK;
96}
97
98
99static status_t
100midi_control(void* cookie, uint32 iop, void* data, size_t len)
101{
102	LOG(("midi_control()\n"));
103
104	return B_ERROR;
105}
106
107
108static status_t
109midi_read(void* cookie, off_t pos, void* ptr, size_t* nread)
110{
111	echo_dev *card = (echo_dev *) cookie;
112	ECHOSTATUS 		err;
113	DWORD			midiData;
114	LONGLONG 		timestamp;
115	PBYTE			next = (PBYTE)ptr;
116
117	LOG(("midi_read()\n"));
118
119	if (acquire_sem(card->midi.midi_ready_sem) != B_OK)
120		return B_ERROR;
121
122	err = card->pEG->ReadMidiByte(&card->midi.context, midiData, timestamp);
123	if (err == ECHOSTATUS_OK) {
124		*nread = 1;
125		*next = midiData;
126		LOG(("midi_read() : 0x%lx\n", *next));
127		return B_OK;
128	}
129	return B_ERROR;
130}
131
132
133static status_t
134midi_write(void* cookie, off_t pos, const void* ptr, size_t* _nwritten)
135{
136	echo_dev *card = (echo_dev *) cookie;
137	ECHOSTATUS err;
138	DWORD nwritten = *_nwritten;
139
140	LOG(("midi_write()\n"));
141
142	err = card->pEG->WriteMidi(nwritten, (PBYTE)ptr, &nwritten);
143	*_nwritten = nwritten;
144	return (err != ECHOSTATUS_OK) ? B_ERROR : B_OK;
145}
146