162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci#ifndef __SOUND_EMUX_SYNTH_H 362306a36Sopenharmony_ci#define __SOUND_EMUX_SYNTH_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Defines for the Emu-series WaveTable chip 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <sound/seq_kernel.h> 1262306a36Sopenharmony_ci#include <sound/seq_device.h> 1362306a36Sopenharmony_ci#include <sound/soundfont.h> 1462306a36Sopenharmony_ci#include <sound/seq_midi_emul.h> 1562306a36Sopenharmony_ci#include <sound/seq_oss.h> 1662306a36Sopenharmony_ci#include <sound/emux_legacy.h> 1762306a36Sopenharmony_ci#include <sound/seq_virmidi.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* 2062306a36Sopenharmony_ci * compile flags 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci#define SNDRV_EMUX_USE_RAW_EFFECT 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct snd_emux; 2562306a36Sopenharmony_cistruct snd_emux_port; 2662306a36Sopenharmony_cistruct snd_emux_voice; 2762306a36Sopenharmony_cistruct snd_emux_effect_table; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * operators 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_cistruct snd_emux_operators { 3362306a36Sopenharmony_ci struct module *owner; 3462306a36Sopenharmony_ci struct snd_emux_voice *(*get_voice)(struct snd_emux *emu, 3562306a36Sopenharmony_ci struct snd_emux_port *port); 3662306a36Sopenharmony_ci int (*prepare)(struct snd_emux_voice *vp); 3762306a36Sopenharmony_ci void (*trigger)(struct snd_emux_voice *vp); 3862306a36Sopenharmony_ci void (*release)(struct snd_emux_voice *vp); 3962306a36Sopenharmony_ci void (*update)(struct snd_emux_voice *vp, int update); 4062306a36Sopenharmony_ci void (*terminate)(struct snd_emux_voice *vp); 4162306a36Sopenharmony_ci void (*free_voice)(struct snd_emux_voice *vp); 4262306a36Sopenharmony_ci void (*reset)(struct snd_emux *emu, int ch); 4362306a36Sopenharmony_ci /* the first parameters are struct snd_emux */ 4462306a36Sopenharmony_ci int (*sample_new)(struct snd_emux *emu, struct snd_sf_sample *sp, 4562306a36Sopenharmony_ci struct snd_util_memhdr *hdr, 4662306a36Sopenharmony_ci const void __user *data, long count); 4762306a36Sopenharmony_ci int (*sample_free)(struct snd_emux *emu, struct snd_sf_sample *sp, 4862306a36Sopenharmony_ci struct snd_util_memhdr *hdr); 4962306a36Sopenharmony_ci void (*sample_reset)(struct snd_emux *emu); 5062306a36Sopenharmony_ci int (*load_fx)(struct snd_emux *emu, int type, int arg, 5162306a36Sopenharmony_ci const void __user *data, long count); 5262306a36Sopenharmony_ci void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed, 5362306a36Sopenharmony_ci struct snd_midi_channel_set *chset); 5462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 5562306a36Sopenharmony_ci int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); 5662306a36Sopenharmony_ci#endif 5762306a36Sopenharmony_ci int (*get_pitch_shift)(struct snd_emux *emu); 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* 6262306a36Sopenharmony_ci * constant values 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ci#define SNDRV_EMUX_MAX_PORTS 32 /* max # of sequencer ports */ 6562306a36Sopenharmony_ci#define SNDRV_EMUX_MAX_VOICES 64 /* max # of voices */ 6662306a36Sopenharmony_ci#define SNDRV_EMUX_MAX_MULTI_VOICES 16 /* max # of playable voices 6762306a36Sopenharmony_ci * simultineously 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * flags 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci#define SNDRV_EMUX_ACCEPT_ROM (1<<0) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* 7662306a36Sopenharmony_ci * emuX wavetable 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_cistruct snd_emux { 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci struct snd_card *card; /* assigned card */ 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci /* following should be initialized before registration */ 8362306a36Sopenharmony_ci int max_voices; /* Number of voices */ 8462306a36Sopenharmony_ci int mem_size; /* memory size (in byte) */ 8562306a36Sopenharmony_ci int num_ports; /* number of ports to be created */ 8662306a36Sopenharmony_ci struct snd_emux_operators ops; /* operators */ 8762306a36Sopenharmony_ci void *hw; /* hardware */ 8862306a36Sopenharmony_ci unsigned long flags; /* other conditions */ 8962306a36Sopenharmony_ci int midi_ports; /* number of virtual midi devices */ 9062306a36Sopenharmony_ci int midi_devidx; /* device offset of virtual midi */ 9162306a36Sopenharmony_ci unsigned int linear_panning: 1; /* panning is linear (sbawe = 1, emu10k1 = 0) */ 9262306a36Sopenharmony_ci int hwdep_idx; /* hwdep device index */ 9362306a36Sopenharmony_ci struct snd_hwdep *hwdep; /* hwdep device */ 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* private */ 9662306a36Sopenharmony_ci int num_voices; /* current number of voices */ 9762306a36Sopenharmony_ci struct snd_sf_list *sflist; /* root of SoundFont list */ 9862306a36Sopenharmony_ci struct snd_emux_voice *voices; /* Voices (EMU 'channel') */ 9962306a36Sopenharmony_ci int use_time; /* allocation counter */ 10062306a36Sopenharmony_ci spinlock_t voice_lock; /* Lock for voice access */ 10162306a36Sopenharmony_ci struct mutex register_mutex; 10262306a36Sopenharmony_ci int client; /* For the sequencer client */ 10362306a36Sopenharmony_ci int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */ 10462306a36Sopenharmony_ci struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS]; 10562306a36Sopenharmony_ci int used; /* use counter */ 10662306a36Sopenharmony_ci char *name; /* name of the device (internal) */ 10762306a36Sopenharmony_ci struct snd_rawmidi **vmidi; 10862306a36Sopenharmony_ci struct timer_list tlist; /* for pending note-offs */ 10962306a36Sopenharmony_ci int timer_active; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci struct snd_util_memhdr *memhdr; /* memory chunk information */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#ifdef CONFIG_SND_PROC_FS 11462306a36Sopenharmony_ci struct snd_info_entry *proc; 11562306a36Sopenharmony_ci#endif 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 11862306a36Sopenharmony_ci struct snd_seq_device *oss_synth; 11962306a36Sopenharmony_ci#endif 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * sequencer port information 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_cistruct snd_emux_port { 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci struct snd_midi_channel_set chset; 12962306a36Sopenharmony_ci struct snd_emux *emu; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci char port_mode; /* operation mode */ 13262306a36Sopenharmony_ci int volume_atten; /* emuX raw attenuation */ 13362306a36Sopenharmony_ci unsigned long drum_flags; /* drum bitmaps */ 13462306a36Sopenharmony_ci int ctrls[EMUX_MD_END]; /* control parameters */ 13562306a36Sopenharmony_ci#ifdef SNDRV_EMUX_USE_RAW_EFFECT 13662306a36Sopenharmony_ci struct snd_emux_effect_table *effect; 13762306a36Sopenharmony_ci#endif 13862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 13962306a36Sopenharmony_ci struct snd_seq_oss_arg *oss_arg; 14062306a36Sopenharmony_ci#endif 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/* port_mode */ 14462306a36Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_MIDI 0 /* normal MIDI port */ 14562306a36Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_OSS_SYNTH 1 /* OSS synth port */ 14662306a36Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_OSS_MIDI 2 /* OSS multi channel synth port */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * A structure to keep track of each hardware voice 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_cistruct snd_emux_voice { 15262306a36Sopenharmony_ci int ch; /* Hardware channel number */ 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci int state; /* status */ 15562306a36Sopenharmony_ci#define SNDRV_EMUX_ST_OFF 0x00 /* Not playing, and inactive */ 15662306a36Sopenharmony_ci#define SNDRV_EMUX_ST_ON 0x01 /* Note on */ 15762306a36Sopenharmony_ci#define SNDRV_EMUX_ST_RELEASED (0x02|SNDRV_EMUX_ST_ON) /* Note released */ 15862306a36Sopenharmony_ci#define SNDRV_EMUX_ST_SUSTAINED (0x04|SNDRV_EMUX_ST_ON) /* Note sustained */ 15962306a36Sopenharmony_ci#define SNDRV_EMUX_ST_STANDBY (0x08|SNDRV_EMUX_ST_ON) /* Waiting to be triggered */ 16062306a36Sopenharmony_ci#define SNDRV_EMUX_ST_PENDING (0x10|SNDRV_EMUX_ST_ON) /* Note will be released */ 16162306a36Sopenharmony_ci#define SNDRV_EMUX_ST_LOCKED 0x100 /* Not accessible */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci unsigned int time; /* An allocation time */ 16462306a36Sopenharmony_ci unsigned char note; /* Note currently assigned to this voice */ 16562306a36Sopenharmony_ci unsigned char key; 16662306a36Sopenharmony_ci unsigned char velocity; /* Velocity of current note */ 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci struct snd_sf_zone *zone; /* Zone assigned to this note */ 16962306a36Sopenharmony_ci void *block; /* sample block pointer (optional) */ 17062306a36Sopenharmony_ci struct snd_midi_channel *chan; /* Midi channel for this note */ 17162306a36Sopenharmony_ci struct snd_emux_port *port; /* associated port */ 17262306a36Sopenharmony_ci struct snd_emux *emu; /* assigned root info */ 17362306a36Sopenharmony_ci void *hw; /* hardware pointer (emu8000 or emu10k1) */ 17462306a36Sopenharmony_ci unsigned long ontime; /* jiffies at note triggered */ 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* Emu8k/Emu10k1 registers */ 17762306a36Sopenharmony_ci struct soundfont_voice_info reg; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* additional registers */ 18062306a36Sopenharmony_ci int avol; /* volume attenuation */ 18162306a36Sopenharmony_ci int acutoff; /* cutoff target */ 18262306a36Sopenharmony_ci int apitch; /* pitch offset */ 18362306a36Sopenharmony_ci int apan; /* pan/aux pair */ 18462306a36Sopenharmony_ci int aaux; 18562306a36Sopenharmony_ci int ptarget; /* pitch target */ 18662306a36Sopenharmony_ci int vtarget; /* volume target */ 18762306a36Sopenharmony_ci int ftarget; /* filter target */ 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* 19262306a36Sopenharmony_ci * update flags (can be combined) 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_VOLUME (1<<0) 19562306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_PITCH (1<<1) 19662306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_PAN (1<<2) 19762306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_FMMOD (1<<3) 19862306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_TREMFREQ (1<<4) 19962306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_FM2FRQ2 (1<<5) 20062306a36Sopenharmony_ci#define SNDRV_EMUX_UPDATE_Q (1<<6) 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#ifdef SNDRV_EMUX_USE_RAW_EFFECT 20462306a36Sopenharmony_ci/* 20562306a36Sopenharmony_ci * effect table 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_cistruct snd_emux_effect_table { 20862306a36Sopenharmony_ci /* Emu8000 specific effects */ 20962306a36Sopenharmony_ci short val[EMUX_NUM_EFFECTS]; 21062306a36Sopenharmony_ci unsigned char flag[EMUX_NUM_EFFECTS]; 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci#endif /* SNDRV_EMUX_USE_RAW_EFFECT */ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci/* 21662306a36Sopenharmony_ci * prototypes - interface to Emu10k1 and Emu8k routines 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ciint snd_emux_new(struct snd_emux **remu); 21962306a36Sopenharmony_ciint snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name); 22062306a36Sopenharmony_ciint snd_emux_free(struct snd_emux *emu); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci/* 22362306a36Sopenharmony_ci * exported functions 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_civoid snd_emux_terminate_all(struct snd_emux *emu); 22662306a36Sopenharmony_civoid snd_emux_lock_voice(struct snd_emux *emu, int voice); 22762306a36Sopenharmony_civoid snd_emux_unlock_voice(struct snd_emux *emu, int voice); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci#endif /* __SOUND_EMUX_SYNTH_H */ 230