diff options
Diffstat (limited to 'ANDROID_3.4.5/sound/synth/emux/emux_oss.c')
-rw-r--r-- | ANDROID_3.4.5/sound/synth/emux/emux_oss.c | 517 |
1 files changed, 0 insertions, 517 deletions
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_oss.c b/ANDROID_3.4.5/sound/synth/emux/emux_oss.c deleted file mode 100644 index 319754cf..00000000 --- a/ANDROID_3.4.5/sound/synth/emux/emux_oss.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Interface for OSS sequencer emulation - * - * Copyright (C) 1999 Takashi Iwai <tiwai@suse.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Changes - * 19990227 Steve Ratcliffe Made separate file and merged in latest - * midi emulation. - */ - - -#ifdef CONFIG_SND_SEQUENCER_OSS - -#include <linux/export.h> -#include <asm/uaccess.h> -#include <sound/core.h> -#include "emux_voice.h" -#include <sound/asoundef.h> - -static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure); -static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg); -static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, - unsigned long ioarg); -static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, - const char __user *buf, int offs, int count); -static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg); -static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, - void *private, int atomic, int hop); -static void reset_port_mode(struct snd_emux_port *port, int midi_mode); -static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, - int cmd, unsigned char *event, int atomic, int hop); -static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, - int cmd, unsigned char *event, int atomic, int hop); -static void fake_event(struct snd_emux *emu, struct snd_emux_port *port, - int ch, int param, int val, int atomic, int hop); - -/* operators */ -static struct snd_seq_oss_callback oss_callback = { - .owner = THIS_MODULE, - .open = snd_emux_open_seq_oss, - .close = snd_emux_close_seq_oss, - .ioctl = snd_emux_ioctl_seq_oss, - .load_patch = snd_emux_load_patch_seq_oss, - .reset = snd_emux_reset_seq_oss, -}; - - -/* - * register OSS synth - */ - -void -snd_emux_init_seq_oss(struct snd_emux *emu) -{ - struct snd_seq_oss_reg *arg; - struct snd_seq_device *dev; - - if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS, - sizeof(struct snd_seq_oss_reg), &dev) < 0) - return; - - emu->oss_synth = dev; - strcpy(dev->name, emu->name); - arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); - arg->type = SYNTH_TYPE_SAMPLE; - arg->subtype = SAMPLE_TYPE_AWE32; - arg->nvoices = emu->max_voices; - arg->oper = oss_callback; - arg->private_data = emu; - - /* register to OSS synth table */ - snd_device_register(emu->card, dev); -} - - -/* - * unregister - */ -void -snd_emux_detach_seq_oss(struct snd_emux *emu) -{ - if (emu->oss_synth) { - snd_device_free(emu->card, emu->oss_synth); - emu->oss_synth = NULL; - } -} - - -/* use port number as a unique soundfont client number */ -#define SF_CLIENT_NO(p) ((p) + 0x1000) - -/* - * open port for OSS sequencer - */ -static int -snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) -{ - struct snd_emux *emu; - struct snd_emux_port *p; - struct snd_seq_port_callback callback; - char tmpname[64]; - - emu = closure; - if (snd_BUG_ON(!arg || !emu)) - return -ENXIO; - - mutex_lock(&emu->register_mutex); - - if (!snd_emux_inc_count(emu)) { - mutex_unlock(&emu->register_mutex); - return -EFAULT; - } - - memset(&callback, 0, sizeof(callback)); - callback.owner = THIS_MODULE; - callback.event_input = snd_emux_event_oss_input; - - sprintf(tmpname, "%s OSS Port", emu->name); - p = snd_emux_create_port(emu, tmpname, 32, - 1, &callback); - if (p == NULL) { - snd_printk(KERN_ERR "can't create port\n"); - snd_emux_dec_count(emu); - mutex_unlock(&emu->register_mutex); - return -ENOMEM; - } - - /* fill the argument data */ - arg->private_data = p; - arg->addr.client = p->chset.client; - arg->addr.port = p->chset.port; - p->oss_arg = arg; - - reset_port_mode(p, arg->seq_mode); - - snd_emux_reset_port(p); - - mutex_unlock(&emu->register_mutex); - return 0; -} - - -#define DEFAULT_DRUM_FLAGS ((1<<9) | (1<<25)) - -/* - * reset port mode - */ -static void -reset_port_mode(struct snd_emux_port *port, int midi_mode) -{ - if (midi_mode) { - port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI; - port->drum_flags = DEFAULT_DRUM_FLAGS; - port->volume_atten = 0; - port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_KEYPRESS; - } else { - port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_SYNTH; - port->drum_flags = 0; - port->volume_atten = 32; - port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS; - } -} - - -/* - * close port - */ -static int -snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg) -{ - struct snd_emux *emu; - struct snd_emux_port *p; - - if (snd_BUG_ON(!arg)) - return -ENXIO; - p = arg->private_data; - if (snd_BUG_ON(!p)) - return -ENXIO; - - emu = p->emu; - if (snd_BUG_ON(!emu)) - return -ENXIO; - - mutex_lock(&emu->register_mutex); - snd_emux_sounds_off_all(p); - snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port)); - snd_seq_event_port_detach(p->chset.client, p->chset.port); - snd_emux_dec_count(emu); - - mutex_unlock(&emu->register_mutex); - return 0; -} - - -/* - * load patch - */ -static int -snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, - const char __user *buf, int offs, int count) -{ - struct snd_emux *emu; - struct snd_emux_port *p; - int rc; - - if (snd_BUG_ON(!arg)) - return -ENXIO; - p = arg->private_data; - if (snd_BUG_ON(!p)) - return -ENXIO; - - emu = p->emu; - if (snd_BUG_ON(!emu)) - return -ENXIO; - - if (format == GUS_PATCH) - rc = snd_soundfont_load_guspatch(emu->sflist, buf, count, - SF_CLIENT_NO(p->chset.port)); - else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { - struct soundfont_patch_info patch; - if (count < (int)sizeof(patch)) - rc = -EINVAL; - if (copy_from_user(&patch, buf, sizeof(patch))) - rc = -EFAULT; - if (patch.type >= SNDRV_SFNT_LOAD_INFO && - patch.type <= SNDRV_SFNT_PROBE_DATA) - rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port)); - else { - if (emu->ops.load_fx) - rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count); - else - rc = -EINVAL; - } - } else - rc = 0; - return rc; -} - - -/* - * ioctl - */ -static int -snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg) -{ - struct snd_emux_port *p; - struct snd_emux *emu; - - if (snd_BUG_ON(!arg)) - return -ENXIO; - p = arg->private_data; - if (snd_BUG_ON(!p)) - return -ENXIO; - - emu = p->emu; - if (snd_BUG_ON(!emu)) - return -ENXIO; - - switch (cmd) { - case SNDCTL_SEQ_RESETSAMPLES: - snd_soundfont_remove_samples(emu->sflist); - return 0; - - case SNDCTL_SYNTH_MEMAVL: - if (emu->memhdr) - return snd_util_mem_avail(emu->memhdr); - return 0; - } - - return 0; -} - - -/* - * reset device - */ -static int -snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg) -{ - struct snd_emux_port *p; - - 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. - */ -static int -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; - unsigned char 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 - */ -static void -emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, - unsigned char *event, int atomic, int hop) -{ - int voice; - unsigned short p1; - short p2; - int i; - struct snd_midi_channel *chan; - - voice = event[3]; - if (voice < 0 || voice >= port->chset.max_channels) - chan = NULL; - else - chan = &port->chset.channels[voice]; - - p1 = *(unsigned short *) &event[4]; - p2 = *(short *) &event[6]; - - 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 = *(unsigned int*)&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> - -static void -gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, - unsigned char *event, int atomic, int hop) -{ - int voice; - unsigned short p1; - short p2; - 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; - - chan = &port->chset.channels[voice]; - - p1 = *(unsigned short *) &event[4]; - p2 = *(short *) &event[6]; - plong = *(int*) &event[4]; - - switch (cmd) { - case _GUS_VOICESAMPLE: - chan->midi_program = p1; - return; - - case _GUS_VOICEBALA: - /* 0 to 15 --> 0 to 127 */ - chan->control[MIDI_CTL_MSB_PAN] = (int)p1 << 3; - snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN); - return; - - case _GUS_VOICEVOL: - case _GUS_VOICEVOL2: - /* not supported yet */ - return; - - case _GUS_RAMPRANGE: - case _GUS_RAMPRATE: - case _GUS_RAMPMODE: - case _GUS_RAMPON: - case _GUS_RAMPOFF: - /* volume ramping not supported */ - return; - - case _GUS_VOLUME_SCALE: - return; - - case _GUS_VOICE_POS: -#ifdef SNDRV_EMUX_USE_RAW_EFFECT - snd_emux_send_effect(port, chan, EMUX_FX_SAMPLE_START, - (short)(plong & 0x7fff), - EMUX_FX_FLAG_SET); - snd_emux_send_effect(port, chan, EMUX_FX_COARSE_SAMPLE_START, - (plong >> 15) & 0xffff, - EMUX_FX_FLAG_SET); -#endif - return; - } -} - - -/* - * send an event to midi emulation - */ -static void -fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop) -{ - struct snd_seq_event ev; - memset(&ev, 0, sizeof(ev)); - ev.type = SNDRV_SEQ_EVENT_CONTROLLER; - ev.data.control.channel = ch; - ev.data.control.param = param; - ev.data.control.value = val; - snd_emux_event_input(&ev, 0, port, atomic, hop); -} - -#endif /* CONFIG_SND_SEQUENCER_OSS */ |