Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/synth/emux/emux_seq.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Midi Sequencer interface routines.
4
*
5
* Copyright (C) 1999 Steve Ratcliffe
6
* Copyright (c) 1999-2000 Takashi Iwai <[email protected]>
7
*/
8
9
#include "emux_voice.h"
10
#include <linux/slab.h>
11
#include <linux/module.h>
12
13
/* Prototypes for static functions */
14
static void free_port(void *private);
15
static void snd_emux_init_port(struct snd_emux_port *p);
16
static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info);
17
static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info);
18
19
/*
20
* MIDI emulation operators
21
*/
22
static const struct snd_midi_op emux_ops = {
23
.note_on = snd_emux_note_on,
24
.note_off = snd_emux_note_off,
25
.key_press = snd_emux_key_press,
26
.note_terminate = snd_emux_terminate_note,
27
.control = snd_emux_control,
28
.nrpn = snd_emux_nrpn,
29
.sysex = snd_emux_sysex,
30
};
31
32
33
/*
34
* number of MIDI channels
35
*/
36
#define MIDI_CHANNELS 16
37
38
/*
39
* type flags for MIDI sequencer port
40
*/
41
#define DEFAULT_MIDI_TYPE (SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |\
42
SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
43
SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
44
SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
45
SNDRV_SEQ_PORT_TYPE_HARDWARE |\
46
SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
47
48
/*
49
* Initialise the EMUX Synth by creating a client and registering
50
* a series of ports.
51
* Each of the ports will contain the 16 midi channels. Applications
52
* can connect to these ports to play midi data.
53
*/
54
int
55
snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index)
56
{
57
int i;
58
struct snd_seq_port_callback pinfo;
59
char tmpname[64];
60
61
emu->client = snd_seq_create_kernel_client(card, index,
62
"%s WaveTable", emu->name);
63
if (emu->client < 0) {
64
dev_err(card->dev, "can't create client\n");
65
return -ENODEV;
66
}
67
68
if (emu->num_ports <= 0) {
69
dev_warn(card->dev, "seqports must be greater than zero\n");
70
emu->num_ports = 1;
71
} else if (emu->num_ports > SNDRV_EMUX_MAX_PORTS) {
72
dev_warn(card->dev,
73
"too many ports. limited max. ports %d\n",
74
SNDRV_EMUX_MAX_PORTS);
75
emu->num_ports = SNDRV_EMUX_MAX_PORTS;
76
}
77
78
memset(&pinfo, 0, sizeof(pinfo));
79
pinfo.owner = THIS_MODULE;
80
pinfo.use = snd_emux_use;
81
pinfo.unuse = snd_emux_unuse;
82
pinfo.event_input = snd_emux_event_input;
83
84
for (i = 0; i < emu->num_ports; i++) {
85
struct snd_emux_port *p;
86
87
sprintf(tmpname, "%s Port %d", emu->name, i);
88
p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS,
89
0, &pinfo);
90
if (!p) {
91
dev_err(card->dev, "can't create port\n");
92
return -ENOMEM;
93
}
94
95
p->port_mode = SNDRV_EMUX_PORT_MODE_MIDI;
96
snd_emux_init_port(p);
97
emu->ports[i] = p->chset.port;
98
emu->portptrs[i] = p;
99
}
100
101
return 0;
102
}
103
104
105
/*
106
* Detach from the ports that were set up for this synthesizer and
107
* destroy the kernel client.
108
*/
109
void
110
snd_emux_detach_seq(struct snd_emux *emu)
111
{
112
if (emu->voices)
113
snd_emux_terminate_all(emu);
114
115
if (emu->client >= 0) {
116
snd_seq_delete_kernel_client(emu->client);
117
emu->client = -1;
118
}
119
}
120
121
122
/*
123
* create a sequencer port and channel_set
124
*/
125
126
struct snd_emux_port *
127
snd_emux_create_port(struct snd_emux *emu, char *name,
128
int max_channels, int oss_port,
129
struct snd_seq_port_callback *callback)
130
{
131
struct snd_emux_port *p;
132
int i, type, cap;
133
134
/* Allocate structures for this channel */
135
p = kzalloc(sizeof(*p), GFP_KERNEL);
136
if (!p)
137
return NULL;
138
139
p->chset.channels = kcalloc(max_channels, sizeof(*p->chset.channels),
140
GFP_KERNEL);
141
if (!p->chset.channels) {
142
kfree(p);
143
return NULL;
144
}
145
for (i = 0; i < max_channels; i++)
146
p->chset.channels[i].number = i;
147
p->chset.private_data = p;
148
p->chset.max_channels = max_channels;
149
p->emu = emu;
150
p->chset.client = emu->client;
151
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
152
snd_emux_create_effect(p);
153
#endif
154
callback->private_free = free_port;
155
callback->private_data = p;
156
157
cap = SNDRV_SEQ_PORT_CAP_WRITE;
158
if (oss_port) {
159
type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
160
} else {
161
type = DEFAULT_MIDI_TYPE;
162
cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
163
}
164
165
p->chset.port = snd_seq_event_port_attach(emu->client, callback,
166
cap, type, max_channels,
167
emu->max_voices, name);
168
169
return p;
170
}
171
172
173
/*
174
* release memory block for port
175
*/
176
static void
177
free_port(void *private_data)
178
{
179
struct snd_emux_port *p;
180
181
p = private_data;
182
if (p) {
183
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
184
snd_emux_delete_effect(p);
185
#endif
186
kfree(p->chset.channels);
187
kfree(p);
188
}
189
}
190
191
192
#define DEFAULT_DRUM_FLAGS (1<<9)
193
194
/*
195
* initialize the port specific parameters
196
*/
197
static void
198
snd_emux_init_port(struct snd_emux_port *p)
199
{
200
p->drum_flags = DEFAULT_DRUM_FLAGS;
201
p->volume_atten = 0;
202
203
snd_emux_reset_port(p);
204
}
205
206
207
/*
208
* reset port
209
*/
210
void
211
snd_emux_reset_port(struct snd_emux_port *port)
212
{
213
int i;
214
215
/* stop all sounds */
216
snd_emux_sounds_off_all(port);
217
218
snd_midi_channel_set_clear(&port->chset);
219
220
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
221
snd_emux_clear_effect(port);
222
#endif
223
224
/* set port specific control parameters */
225
port->ctrls[EMUX_MD_DEF_BANK] = 0;
226
port->ctrls[EMUX_MD_DEF_DRUM] = 0;
227
port->ctrls[EMUX_MD_REALTIME_PAN] = 1;
228
229
for (i = 0; i < port->chset.max_channels; i++) {
230
struct snd_midi_channel *chan = port->chset.channels + i;
231
chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
232
}
233
}
234
235
236
/*
237
* input sequencer event
238
*/
239
int
240
snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
241
int atomic, int hop)
242
{
243
struct snd_emux_port *port;
244
245
port = private_data;
246
if (snd_BUG_ON(!port || !ev))
247
return -EINVAL;
248
249
snd_midi_process_event(&emux_ops, ev, &port->chset);
250
251
return 0;
252
}
253
254
255
/*
256
* increment usage count
257
*/
258
static int
259
__snd_emux_inc_count(struct snd_emux *emu)
260
{
261
emu->used++;
262
if (!try_module_get(emu->ops.owner))
263
goto __error;
264
if (!try_module_get(emu->card->module)) {
265
module_put(emu->ops.owner);
266
__error:
267
emu->used--;
268
return 0;
269
}
270
return 1;
271
}
272
273
int snd_emux_inc_count(struct snd_emux *emu)
274
{
275
guard(mutex)(&emu->register_mutex);
276
return __snd_emux_inc_count(emu);
277
}
278
279
/*
280
* decrease usage count
281
*/
282
static void
283
__snd_emux_dec_count(struct snd_emux *emu)
284
{
285
module_put(emu->card->module);
286
emu->used--;
287
if (emu->used <= 0)
288
snd_emux_terminate_all(emu);
289
module_put(emu->ops.owner);
290
}
291
292
void snd_emux_dec_count(struct snd_emux *emu)
293
{
294
guard(mutex)(&emu->register_mutex);
295
__snd_emux_dec_count(emu);
296
}
297
298
/*
299
* Routine that is called upon a first use of a particular port
300
*/
301
static int
302
snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
303
{
304
struct snd_emux_port *p;
305
struct snd_emux *emu;
306
307
p = private_data;
308
if (snd_BUG_ON(!p))
309
return -EINVAL;
310
emu = p->emu;
311
if (snd_BUG_ON(!emu))
312
return -EINVAL;
313
314
guard(mutex)(&emu->register_mutex);
315
snd_emux_init_port(p);
316
__snd_emux_inc_count(emu);
317
return 0;
318
}
319
320
/*
321
* Routine that is called upon the last unuse() of a particular port.
322
*/
323
static int
324
snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
325
{
326
struct snd_emux_port *p;
327
struct snd_emux *emu;
328
329
p = private_data;
330
if (snd_BUG_ON(!p))
331
return -EINVAL;
332
emu = p->emu;
333
if (snd_BUG_ON(!emu))
334
return -EINVAL;
335
336
guard(mutex)(&emu->register_mutex);
337
snd_emux_sounds_off_all(p);
338
__snd_emux_dec_count(emu);
339
return 0;
340
}
341
342
343
/*
344
* attach virtual rawmidi devices
345
*/
346
int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card)
347
{
348
int i;
349
350
emu->vmidi = NULL;
351
if (emu->midi_ports <= 0)
352
return 0;
353
354
emu->vmidi = kcalloc(emu->midi_ports, sizeof(*emu->vmidi), GFP_KERNEL);
355
if (!emu->vmidi)
356
return -ENOMEM;
357
358
for (i = 0; i < emu->midi_ports; i++) {
359
struct snd_rawmidi *rmidi;
360
struct snd_virmidi_dev *rdev;
361
if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
362
goto __error;
363
rdev = rmidi->private_data;
364
sprintf(rmidi->name, "%s Synth MIDI", emu->name);
365
rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
366
rdev->client = emu->client;
367
rdev->port = emu->ports[i];
368
if (snd_device_register(card, rmidi) < 0) {
369
snd_device_free(card, rmidi);
370
goto __error;
371
}
372
emu->vmidi[i] = rmidi;
373
}
374
return 0;
375
376
__error:
377
snd_emux_delete_virmidi(emu);
378
return -ENOMEM;
379
}
380
381
int snd_emux_delete_virmidi(struct snd_emux *emu)
382
{
383
int i;
384
385
if (!emu->vmidi)
386
return 0;
387
388
for (i = 0; i < emu->midi_ports; i++) {
389
if (emu->vmidi[i])
390
snd_device_free(emu->card, emu->vmidi[i]);
391
}
392
kfree(emu->vmidi);
393
emu->vmidi = NULL;
394
return 0;
395
}
396
397