0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/export.h>
0014 #include <linux/uaccess.h>
0015 #include <sound/core.h>
0016 #include "emux_voice.h"
0017 #include <sound/asoundef.h>
0018
0019 static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
0020 static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg);
0021 static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
0022 unsigned long ioarg);
0023 static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
0024 const char __user *buf, int offs, int count);
0025 static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg);
0026 static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct,
0027 void *private, int atomic, int hop);
0028 static void reset_port_mode(struct snd_emux_port *port, int midi_mode);
0029 static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port,
0030 int cmd, unsigned char *event, int atomic, int hop);
0031 static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port,
0032 int cmd, unsigned char *event, int atomic, int hop);
0033 static void fake_event(struct snd_emux *emu, struct snd_emux_port *port,
0034 int ch, int param, int val, int atomic, int hop);
0035
0036
0037 static const struct snd_seq_oss_callback oss_callback = {
0038 .owner = THIS_MODULE,
0039 .open = snd_emux_open_seq_oss,
0040 .close = snd_emux_close_seq_oss,
0041 .ioctl = snd_emux_ioctl_seq_oss,
0042 .load_patch = snd_emux_load_patch_seq_oss,
0043 .reset = snd_emux_reset_seq_oss,
0044 };
0045
0046
0047
0048
0049
0050
0051 void
0052 snd_emux_init_seq_oss(struct snd_emux *emu)
0053 {
0054 struct snd_seq_oss_reg *arg;
0055 struct snd_seq_device *dev;
0056
0057
0058 if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS,
0059 sizeof(struct snd_seq_oss_reg), &dev) < 0)
0060 return;
0061
0062 emu->oss_synth = dev;
0063 strcpy(dev->name, emu->name);
0064 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
0065 arg->type = SYNTH_TYPE_SAMPLE;
0066 arg->subtype = SAMPLE_TYPE_AWE32;
0067 arg->nvoices = emu->max_voices;
0068 arg->oper = oss_callback;
0069 arg->private_data = emu;
0070
0071
0072 snd_device_register(emu->card, dev);
0073 }
0074
0075
0076
0077
0078
0079 void
0080 snd_emux_detach_seq_oss(struct snd_emux *emu)
0081 {
0082 if (emu->oss_synth) {
0083 snd_device_free(emu->card, emu->oss_synth);
0084 emu->oss_synth = NULL;
0085 }
0086 }
0087
0088
0089
0090 #define SF_CLIENT_NO(p) ((p) + 0x1000)
0091
0092
0093
0094
0095 static int
0096 snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
0097 {
0098 struct snd_emux *emu;
0099 struct snd_emux_port *p;
0100 struct snd_seq_port_callback callback;
0101 char tmpname[64];
0102
0103 emu = closure;
0104 if (snd_BUG_ON(!arg || !emu))
0105 return -ENXIO;
0106
0107 if (!snd_emux_inc_count(emu))
0108 return -EFAULT;
0109
0110 memset(&callback, 0, sizeof(callback));
0111 callback.owner = THIS_MODULE;
0112 callback.event_input = snd_emux_event_oss_input;
0113
0114 sprintf(tmpname, "%s OSS Port", emu->name);
0115 p = snd_emux_create_port(emu, tmpname, 32,
0116 1, &callback);
0117 if (p == NULL) {
0118 snd_printk(KERN_ERR "can't create port\n");
0119 snd_emux_dec_count(emu);
0120 return -ENOMEM;
0121 }
0122
0123
0124 arg->private_data = p;
0125 arg->addr.client = p->chset.client;
0126 arg->addr.port = p->chset.port;
0127 p->oss_arg = arg;
0128
0129 reset_port_mode(p, arg->seq_mode);
0130
0131 snd_emux_reset_port(p);
0132 return 0;
0133 }
0134
0135
0136 #define DEFAULT_DRUM_FLAGS ((1<<9) | (1<<25))
0137
0138
0139
0140
0141 static void
0142 reset_port_mode(struct snd_emux_port *port, int midi_mode)
0143 {
0144 if (midi_mode) {
0145 port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI;
0146 port->drum_flags = DEFAULT_DRUM_FLAGS;
0147 port->volume_atten = 0;
0148 port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_KEYPRESS;
0149 } else {
0150 port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_SYNTH;
0151 port->drum_flags = 0;
0152 port->volume_atten = 32;
0153 port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS;
0154 }
0155 }
0156
0157
0158
0159
0160
0161 static int
0162 snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
0163 {
0164 struct snd_emux *emu;
0165 struct snd_emux_port *p;
0166
0167 if (snd_BUG_ON(!arg))
0168 return -ENXIO;
0169 p = arg->private_data;
0170 if (snd_BUG_ON(!p))
0171 return -ENXIO;
0172
0173 emu = p->emu;
0174 if (snd_BUG_ON(!emu))
0175 return -ENXIO;
0176
0177 snd_emux_sounds_off_all(p);
0178 snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
0179 snd_seq_event_port_detach(p->chset.client, p->chset.port);
0180 snd_emux_dec_count(emu);
0181
0182 return 0;
0183 }
0184
0185
0186
0187
0188
0189 static int
0190 snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
0191 const char __user *buf, int offs, int count)
0192 {
0193 struct snd_emux *emu;
0194 struct snd_emux_port *p;
0195 int rc;
0196
0197 if (snd_BUG_ON(!arg))
0198 return -ENXIO;
0199 p = arg->private_data;
0200 if (snd_BUG_ON(!p))
0201 return -ENXIO;
0202
0203 emu = p->emu;
0204 if (snd_BUG_ON(!emu))
0205 return -ENXIO;
0206
0207 if (format == GUS_PATCH)
0208 rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
0209 SF_CLIENT_NO(p->chset.port));
0210 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
0211 struct soundfont_patch_info patch;
0212 if (count < (int)sizeof(patch))
0213 return -EINVAL;
0214 if (copy_from_user(&patch, buf, sizeof(patch)))
0215 return -EFAULT;
0216 if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
0217 patch.type <= SNDRV_SFNT_PROBE_DATA)
0218 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
0219 else {
0220 if (emu->ops.load_fx)
0221 rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count);
0222 else
0223 rc = -EINVAL;
0224 }
0225 } else
0226 rc = 0;
0227 return rc;
0228 }
0229
0230
0231
0232
0233
0234 static int
0235 snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg)
0236 {
0237 struct snd_emux_port *p;
0238 struct snd_emux *emu;
0239
0240 if (snd_BUG_ON(!arg))
0241 return -ENXIO;
0242 p = arg->private_data;
0243 if (snd_BUG_ON(!p))
0244 return -ENXIO;
0245
0246 emu = p->emu;
0247 if (snd_BUG_ON(!emu))
0248 return -ENXIO;
0249
0250 switch (cmd) {
0251 case SNDCTL_SEQ_RESETSAMPLES:
0252 snd_soundfont_remove_samples(emu->sflist);
0253 return 0;
0254
0255 case SNDCTL_SYNTH_MEMAVL:
0256 if (emu->memhdr)
0257 return snd_util_mem_avail(emu->memhdr);
0258 return 0;
0259 }
0260
0261 return 0;
0262 }
0263
0264
0265
0266
0267
0268 static int
0269 snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg)
0270 {
0271 struct snd_emux_port *p;
0272
0273 if (snd_BUG_ON(!arg))
0274 return -ENXIO;
0275 p = arg->private_data;
0276 if (snd_BUG_ON(!p))
0277 return -ENXIO;
0278 snd_emux_reset_port(p);
0279 return 0;
0280 }
0281
0282
0283
0284
0285
0286 static int
0287 snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data,
0288 int atomic, int hop)
0289 {
0290 struct snd_emux *emu;
0291 struct snd_emux_port *p;
0292 unsigned char cmd, *data;
0293
0294 p = private_data;
0295 if (snd_BUG_ON(!p))
0296 return -EINVAL;
0297 emu = p->emu;
0298 if (snd_BUG_ON(!emu))
0299 return -EINVAL;
0300 if (ev->type != SNDRV_SEQ_EVENT_OSS)
0301 return snd_emux_event_input(ev, direct, private_data, atomic, hop);
0302
0303 data = ev->data.raw8.d;
0304
0305 if (data[0] != 0xfe)
0306 return 0;
0307 cmd = data[2] & _EMUX_OSS_MODE_VALUE_MASK;
0308 if (data[2] & _EMUX_OSS_MODE_FLAG)
0309 emuspec_control(emu, p, cmd, data, atomic, hop);
0310 else
0311 gusspec_control(emu, p, cmd, data, atomic, hop);
0312 return 0;
0313 }
0314
0315
0316
0317
0318
0319 static void
0320 emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
0321 unsigned char *event, int atomic, int hop)
0322 {
0323 int voice;
0324 unsigned short p1;
0325 short p2;
0326 int i;
0327 struct snd_midi_channel *chan;
0328
0329 voice = event[3];
0330 if (voice < 0 || voice >= port->chset.max_channels)
0331 chan = NULL;
0332 else
0333 chan = &port->chset.channels[voice];
0334
0335 p1 = *(unsigned short *) &event[4];
0336 p2 = *(short *) &event[6];
0337
0338 switch (cmd) {
0339 #if 0
0340 case _EMUX_OSS_REMOVE_LAST_SAMPLES:
0341 snd_soundfont_remove_unlocked(emu->sflist);
0342 break;
0343 #endif
0344 case _EMUX_OSS_SEND_EFFECT:
0345 if (chan)
0346 snd_emux_send_effect_oss(port, chan, p1, p2);
0347 break;
0348
0349 case _EMUX_OSS_TERMINATE_ALL:
0350 snd_emux_terminate_all(emu);
0351 break;
0352
0353 case _EMUX_OSS_TERMINATE_CHANNEL:
0354
0355 break;
0356 case _EMUX_OSS_RESET_CHANNEL:
0357
0358 break;
0359
0360 case _EMUX_OSS_RELEASE_ALL:
0361 fake_event(emu, port, voice, MIDI_CTL_ALL_NOTES_OFF, 0, atomic, hop);
0362 break;
0363 case _EMUX_OSS_NOTEOFF_ALL:
0364 fake_event(emu, port, voice, MIDI_CTL_ALL_SOUNDS_OFF, 0, atomic, hop);
0365 break;
0366
0367 case _EMUX_OSS_INITIAL_VOLUME:
0368 if (p2) {
0369 port->volume_atten = (short)p1;
0370 snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
0371 }
0372 break;
0373
0374 case _EMUX_OSS_CHN_PRESSURE:
0375 if (chan) {
0376 chan->midi_pressure = p1;
0377 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_FMMOD|SNDRV_EMUX_UPDATE_FM2FRQ2);
0378 }
0379 break;
0380
0381 case _EMUX_OSS_CHANNEL_MODE:
0382 reset_port_mode(port, p1);
0383 snd_emux_reset_port(port);
0384 break;
0385
0386 case _EMUX_OSS_DRUM_CHANNELS:
0387 port->drum_flags = *(unsigned int*)&event[4];
0388 for (i = 0; i < port->chset.max_channels; i++) {
0389 chan = &port->chset.channels[i];
0390 chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
0391 }
0392 break;
0393
0394 case _EMUX_OSS_MISC_MODE:
0395 if (p1 < EMUX_MD_END)
0396 port->ctrls[p1] = p2;
0397 break;
0398 case _EMUX_OSS_DEBUG_MODE:
0399 break;
0400
0401 default:
0402 if (emu->ops.oss_ioctl)
0403 emu->ops.oss_ioctl(emu, cmd, p1, p2);
0404 break;
0405 }
0406 }
0407
0408
0409
0410
0411
0412 #include <linux/ultrasound.h>
0413
0414 static void
0415 gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
0416 unsigned char *event, int atomic, int hop)
0417 {
0418 int voice;
0419 unsigned short p1;
0420 int plong;
0421 struct snd_midi_channel *chan;
0422
0423 if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH)
0424 return;
0425 if (cmd == _GUS_NUMVOICES)
0426 return;
0427 voice = event[3];
0428 if (voice < 0 || voice >= port->chset.max_channels)
0429 return;
0430
0431 chan = &port->chset.channels[voice];
0432
0433 p1 = *(unsigned short *) &event[4];
0434 plong = *(int*) &event[4];
0435
0436 switch (cmd) {
0437 case _GUS_VOICESAMPLE:
0438 chan->midi_program = p1;
0439 return;
0440
0441 case _GUS_VOICEBALA:
0442
0443 chan->control[MIDI_CTL_MSB_PAN] = (int)p1 << 3;
0444 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
0445 return;
0446
0447 case _GUS_VOICEVOL:
0448 case _GUS_VOICEVOL2:
0449
0450 return;
0451
0452 case _GUS_RAMPRANGE:
0453 case _GUS_RAMPRATE:
0454 case _GUS_RAMPMODE:
0455 case _GUS_RAMPON:
0456 case _GUS_RAMPOFF:
0457
0458 return;
0459
0460 case _GUS_VOLUME_SCALE:
0461 return;
0462
0463 case _GUS_VOICE_POS:
0464 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0465 snd_emux_send_effect(port, chan, EMUX_FX_SAMPLE_START,
0466 (short)(plong & 0x7fff),
0467 EMUX_FX_FLAG_SET);
0468 snd_emux_send_effect(port, chan, EMUX_FX_COARSE_SAMPLE_START,
0469 (plong >> 15) & 0xffff,
0470 EMUX_FX_FLAG_SET);
0471 #endif
0472 return;
0473 }
0474 }
0475
0476
0477
0478
0479
0480 static void
0481 fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop)
0482 {
0483 struct snd_seq_event ev;
0484 memset(&ev, 0, sizeof(ev));
0485 ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
0486 ev.data.control.channel = ch;
0487 ev.data.control.param = param;
0488 ev.data.control.value = val;
0489 snd_emux_event_input(&ev, 0, port, atomic, hop);
0490 }