403 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Midi Sequencer interface routines.4 *5 * Copyright (C) 1999 Steve Ratcliffe6 * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>7 */8 9#include "emux_voice.h"10#include <linux/slab.h>11#include <linux/module.h>12 13/* Prototypes for static functions */14static void free_port(void *private);15static void snd_emux_init_port(struct snd_emux_port *p);16static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info);17static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info);18 19/*20 * MIDI emulation operators21 */22static 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 channels35 */36#define MIDI_CHANNELS 1637 38/*39 * type flags for MIDI sequencer port40 */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 registering50 * a series of ports.51 * Each of the ports will contain the 16 midi channels. Applications52 * can connect to these ports to play midi data.53 */54int55snd_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 and107 * destroy the kernel client.108 */109void110snd_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_set124 */125 126struct snd_emux_port *127snd_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_EFFECT152 snd_emux_create_effect(p);153#endif154 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 port175 */176static void177free_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_EFFECT184 snd_emux_delete_effect(p);185#endif186 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 parameters196 */197static void198snd_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 port209 */210void211snd_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_EFFECT221 snd_emux_clear_effect(port);222#endif223 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 event238 */239int240snd_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 count257 */258static int259__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 273int snd_emux_inc_count(struct snd_emux *emu)274{275 int ret;276 277 mutex_lock(&emu->register_mutex);278 ret = __snd_emux_inc_count(emu);279 mutex_unlock(&emu->register_mutex);280 return ret;281}282 283/*284 * decrease usage count285 */286static void287__snd_emux_dec_count(struct snd_emux *emu)288{289 module_put(emu->card->module);290 emu->used--;291 if (emu->used <= 0)292 snd_emux_terminate_all(emu);293 module_put(emu->ops.owner);294}295 296void snd_emux_dec_count(struct snd_emux *emu)297{298 mutex_lock(&emu->register_mutex);299 __snd_emux_dec_count(emu);300 mutex_unlock(&emu->register_mutex);301}302 303/*304 * Routine that is called upon a first use of a particular port305 */306static int307snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)308{309 struct snd_emux_port *p;310 struct snd_emux *emu;311 312 p = private_data;313 if (snd_BUG_ON(!p))314 return -EINVAL;315 emu = p->emu;316 if (snd_BUG_ON(!emu))317 return -EINVAL;318 319 mutex_lock(&emu->register_mutex);320 snd_emux_init_port(p);321 __snd_emux_inc_count(emu);322 mutex_unlock(&emu->register_mutex);323 return 0;324}325 326/*327 * Routine that is called upon the last unuse() of a particular port.328 */329static int330snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)331{332 struct snd_emux_port *p;333 struct snd_emux *emu;334 335 p = private_data;336 if (snd_BUG_ON(!p))337 return -EINVAL;338 emu = p->emu;339 if (snd_BUG_ON(!emu))340 return -EINVAL;341 342 mutex_lock(&emu->register_mutex);343 snd_emux_sounds_off_all(p);344 __snd_emux_dec_count(emu);345 mutex_unlock(&emu->register_mutex);346 return 0;347}348 349 350/*351 * attach virtual rawmidi devices352 */353int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card)354{355 int i;356 357 emu->vmidi = NULL;358 if (emu->midi_ports <= 0)359 return 0;360 361 emu->vmidi = kcalloc(emu->midi_ports, sizeof(*emu->vmidi), GFP_KERNEL);362 if (!emu->vmidi)363 return -ENOMEM;364 365 for (i = 0; i < emu->midi_ports; i++) {366 struct snd_rawmidi *rmidi;367 struct snd_virmidi_dev *rdev;368 if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)369 goto __error;370 rdev = rmidi->private_data;371 sprintf(rmidi->name, "%s Synth MIDI", emu->name);372 rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;373 rdev->client = emu->client;374 rdev->port = emu->ports[i];375 if (snd_device_register(card, rmidi) < 0) {376 snd_device_free(card, rmidi);377 goto __error;378 }379 emu->vmidi[i] = rmidi;380 }381 return 0;382 383__error:384 snd_emux_delete_virmidi(emu);385 return -ENOMEM;386}387 388int snd_emux_delete_virmidi(struct snd_emux *emu)389{390 int i;391 392 if (!emu->vmidi)393 return 0;394 395 for (i = 0; i < emu->midi_ports; i++) {396 if (emu->vmidi[i])397 snd_device_free(emu->card, emu->vmidi[i]);398 }399 kfree(emu->vmidi);400 emu->vmidi = NULL;401 return 0;402}403