/* using device#1 here for avoiding conflicts with OPL3 */ if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS, sizeof(struct snd_seq_oss_reg), &dev) < 0) return;
if (snd_BUG_ON(!arg)) return -ENXIO;
p = arg->private_data; if (snd_BUG_ON(!p)) return -ENXIO;
snd_emux_reset_port(p); return 0;
}
/* * receive raw events: only SEQ_PRIVATE is accepted.
*/ staticint
snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop)
{ struct snd_emux *emu; struct snd_emux_port *p; unsignedchar cmd, *data;
p = private_data; if (snd_BUG_ON(!p)) return -EINVAL;
emu = p->emu; if (snd_BUG_ON(!emu)) return -EINVAL; if (ev->type != SNDRV_SEQ_EVENT_OSS) return snd_emux_event_input(ev, direct, private_data, atomic, hop);
data = ev->data.raw8.d; /* only SEQ_PRIVATE is accepted */ if (data[0] != 0xfe) return 0;
cmd = data[2] & _EMUX_OSS_MODE_VALUE_MASK; if (data[2] & _EMUX_OSS_MODE_FLAG)
emuspec_control(emu, p, cmd, data, atomic, hop); else
gusspec_control(emu, p, cmd, data, atomic, hop); return 0;
}
/* * OSS/AWE driver specific h/w controls
*/ staticvoid
emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, unsignedchar *event, int atomic, int hop)
{ int voice; unsignedshort p1; short p2; int i; struct snd_midi_channel *chan;
switch (cmd) { #if 0 /* don't do this atomically */ case _EMUX_OSS_REMOVE_LAST_SAMPLES:
snd_soundfont_remove_unlocked(emu->sflist); break; #endif case _EMUX_OSS_SEND_EFFECT: if (chan)
snd_emux_send_effect_oss(port, chan, p1, p2); break;
case _EMUX_OSS_TERMINATE_ALL:
snd_emux_terminate_all(emu); break;
case _EMUX_OSS_TERMINATE_CHANNEL: /*snd_emux_mute_channel(emu, chan);*/ break; case _EMUX_OSS_RESET_CHANNEL: /*snd_emux_channel_init(chset, chan);*/ break;
case _EMUX_OSS_RELEASE_ALL:
fake_event(emu, port, voice, MIDI_CTL_ALL_NOTES_OFF, 0, atomic, hop); break; case _EMUX_OSS_NOTEOFF_ALL:
fake_event(emu, port, voice, MIDI_CTL_ALL_SOUNDS_OFF, 0, atomic, hop); break;
case _EMUX_OSS_INITIAL_VOLUME: if (p2) {
port->volume_atten = (short)p1;
snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
} break;
case _EMUX_OSS_CHN_PRESSURE: if (chan) {
chan->midi_pressure = p1;
snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_FMMOD|SNDRV_EMUX_UPDATE_FM2FRQ2);
} break;
case _EMUX_OSS_CHANNEL_MODE:
reset_port_mode(port, p1);
snd_emux_reset_port(port); break;
case _EMUX_OSS_DRUM_CHANNELS:
port->drum_flags = *(unsignedint*)&event[4]; for (i = 0; i < port->chset.max_channels; i++) {
chan = &port->chset.channels[i];
chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
} break;
case _EMUX_OSS_MISC_MODE: if (p1 < EMUX_MD_END)
port->ctrls[p1] = p2; break; case _EMUX_OSS_DEBUG_MODE: break;
default: if (emu->ops.oss_ioctl)
emu->ops.oss_ioctl(emu, cmd, p1, p2); break;
}
}
/* * GUS specific h/w controls
*/
#include <linux/ultrasound.h>
staticvoid
gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, unsignedchar *event, int atomic, int hop)
{ int voice; unsignedshort p1; int plong; struct snd_midi_channel *chan;
if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH) return; if (cmd == _GUS_NUMVOICES) return;
voice = event[3]; if (voice < 0 || voice >= port->chset.max_channels) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.