xref: /haiku/src/add-ons/kernel/drivers/audio/echo/midi.cpp (revision 29f8805f6c70f1c819eb58ac2220647d8e40d6e7)
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 
29 static status_t midi_open(const char *name, uint32 flags, void **cookie);
30 static status_t midi_close(void *cookie);
31 static status_t midi_free(void *cookie);
32 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
33 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
34 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
35 
36 
37 device_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 
50 static status_t
51 midi_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 
76 static status_t
77 midi_close(void* cookie)
78 {
79 	LOG(("midi_close()\n"));
80 	return B_OK;
81 }
82 
83 
84 static status_t
85 midi_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 
99 static status_t
100 midi_control(void* cookie, uint32 iop, void* data, size_t len)
101 {
102 	LOG(("midi_control()\n"));
103 
104 	return B_ERROR;
105 }
106 
107 
108 static status_t
109 midi_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 
133 static status_t
134 midi_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