18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci#ifndef __SOUND_EMUX_SYNTH_H 38c2ecf20Sopenharmony_ci#define __SOUND_EMUX_SYNTH_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * Defines for the Emu-series WaveTable chip 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <sound/seq_kernel.h> 128c2ecf20Sopenharmony_ci#include <sound/seq_device.h> 138c2ecf20Sopenharmony_ci#include <sound/soundfont.h> 148c2ecf20Sopenharmony_ci#include <sound/seq_midi_emul.h> 158c2ecf20Sopenharmony_ci#include <sound/seq_oss.h> 168c2ecf20Sopenharmony_ci#include <sound/emux_legacy.h> 178c2ecf20Sopenharmony_ci#include <sound/seq_virmidi.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * compile flags 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci#define SNDRV_EMUX_USE_RAW_EFFECT 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistruct snd_emux; 258c2ecf20Sopenharmony_cistruct snd_emux_port; 268c2ecf20Sopenharmony_cistruct snd_emux_voice; 278c2ecf20Sopenharmony_cistruct snd_emux_effect_table; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * operators 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_cistruct snd_emux_operators { 338c2ecf20Sopenharmony_ci struct module *owner; 348c2ecf20Sopenharmony_ci struct snd_emux_voice *(*get_voice)(struct snd_emux *emu, 358c2ecf20Sopenharmony_ci struct snd_emux_port *port); 368c2ecf20Sopenharmony_ci int (*prepare)(struct snd_emux_voice *vp); 378c2ecf20Sopenharmony_ci void (*trigger)(struct snd_emux_voice *vp); 388c2ecf20Sopenharmony_ci void (*release)(struct snd_emux_voice *vp); 398c2ecf20Sopenharmony_ci void (*update)(struct snd_emux_voice *vp, int update); 408c2ecf20Sopenharmony_ci void (*terminate)(struct snd_emux_voice *vp); 418c2ecf20Sopenharmony_ci void (*free_voice)(struct snd_emux_voice *vp); 428c2ecf20Sopenharmony_ci void (*reset)(struct snd_emux *emu, int ch); 438c2ecf20Sopenharmony_ci /* the first parameters are struct snd_emux */ 448c2ecf20Sopenharmony_ci int (*sample_new)(struct snd_emux *emu, struct snd_sf_sample *sp, 458c2ecf20Sopenharmony_ci struct snd_util_memhdr *hdr, 468c2ecf20Sopenharmony_ci const void __user *data, long count); 478c2ecf20Sopenharmony_ci int (*sample_free)(struct snd_emux *emu, struct snd_sf_sample *sp, 488c2ecf20Sopenharmony_ci struct snd_util_memhdr *hdr); 498c2ecf20Sopenharmony_ci void (*sample_reset)(struct snd_emux *emu); 508c2ecf20Sopenharmony_ci int (*load_fx)(struct snd_emux *emu, int type, int arg, 518c2ecf20Sopenharmony_ci const void __user *data, long count); 528c2ecf20Sopenharmony_ci void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed, 538c2ecf20Sopenharmony_ci struct snd_midi_channel_set *chset); 548c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 558c2ecf20Sopenharmony_ci int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); 568c2ecf20Sopenharmony_ci#endif 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/* 618c2ecf20Sopenharmony_ci * constant values 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ci#define SNDRV_EMUX_MAX_PORTS 32 /* max # of sequencer ports */ 648c2ecf20Sopenharmony_ci#define SNDRV_EMUX_MAX_VOICES 64 /* max # of voices */ 658c2ecf20Sopenharmony_ci#define SNDRV_EMUX_MAX_MULTI_VOICES 16 /* max # of playable voices 668c2ecf20Sopenharmony_ci * simultineously 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* 708c2ecf20Sopenharmony_ci * flags 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ACCEPT_ROM (1<<0) 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* 758c2ecf20Sopenharmony_ci * emuX wavetable 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_cistruct snd_emux { 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci struct snd_card *card; /* assigned card */ 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci /* following should be initialized before registration */ 828c2ecf20Sopenharmony_ci int max_voices; /* Number of voices */ 838c2ecf20Sopenharmony_ci int mem_size; /* memory size (in byte) */ 848c2ecf20Sopenharmony_ci int num_ports; /* number of ports to be created */ 858c2ecf20Sopenharmony_ci int pitch_shift; /* pitch shift value (for Emu10k1) */ 868c2ecf20Sopenharmony_ci struct snd_emux_operators ops; /* operators */ 878c2ecf20Sopenharmony_ci void *hw; /* hardware */ 888c2ecf20Sopenharmony_ci unsigned long flags; /* other conditions */ 898c2ecf20Sopenharmony_ci int midi_ports; /* number of virtual midi devices */ 908c2ecf20Sopenharmony_ci int midi_devidx; /* device offset of virtual midi */ 918c2ecf20Sopenharmony_ci unsigned int linear_panning: 1; /* panning is linear (sbawe = 1, emu10k1 = 0) */ 928c2ecf20Sopenharmony_ci int hwdep_idx; /* hwdep device index */ 938c2ecf20Sopenharmony_ci struct snd_hwdep *hwdep; /* hwdep device */ 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* private */ 968c2ecf20Sopenharmony_ci int num_voices; /* current number of voices */ 978c2ecf20Sopenharmony_ci struct snd_sf_list *sflist; /* root of SoundFont list */ 988c2ecf20Sopenharmony_ci struct snd_emux_voice *voices; /* Voices (EMU 'channel') */ 998c2ecf20Sopenharmony_ci int use_time; /* allocation counter */ 1008c2ecf20Sopenharmony_ci spinlock_t voice_lock; /* Lock for voice access */ 1018c2ecf20Sopenharmony_ci struct mutex register_mutex; 1028c2ecf20Sopenharmony_ci int client; /* For the sequencer client */ 1038c2ecf20Sopenharmony_ci int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */ 1048c2ecf20Sopenharmony_ci struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS]; 1058c2ecf20Sopenharmony_ci int used; /* use counter */ 1068c2ecf20Sopenharmony_ci char *name; /* name of the device (internal) */ 1078c2ecf20Sopenharmony_ci struct snd_rawmidi **vmidi; 1088c2ecf20Sopenharmony_ci struct timer_list tlist; /* for pending note-offs */ 1098c2ecf20Sopenharmony_ci int timer_active; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci struct snd_util_memhdr *memhdr; /* memory chunk information */ 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_PROC_FS 1148c2ecf20Sopenharmony_ci struct snd_info_entry *proc; 1158c2ecf20Sopenharmony_ci#endif 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 1188c2ecf20Sopenharmony_ci struct snd_seq_device *oss_synth; 1198c2ecf20Sopenharmony_ci#endif 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* 1248c2ecf20Sopenharmony_ci * sequencer port information 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_cistruct snd_emux_port { 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci struct snd_midi_channel_set chset; 1298c2ecf20Sopenharmony_ci struct snd_emux *emu; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci char port_mode; /* operation mode */ 1328c2ecf20Sopenharmony_ci int volume_atten; /* emuX raw attenuation */ 1338c2ecf20Sopenharmony_ci unsigned long drum_flags; /* drum bitmaps */ 1348c2ecf20Sopenharmony_ci int ctrls[EMUX_MD_END]; /* control parameters */ 1358c2ecf20Sopenharmony_ci#ifdef SNDRV_EMUX_USE_RAW_EFFECT 1368c2ecf20Sopenharmony_ci struct snd_emux_effect_table *effect; 1378c2ecf20Sopenharmony_ci#endif 1388c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) 1398c2ecf20Sopenharmony_ci struct snd_seq_oss_arg *oss_arg; 1408c2ecf20Sopenharmony_ci#endif 1418c2ecf20Sopenharmony_ci}; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/* port_mode */ 1448c2ecf20Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_MIDI 0 /* normal MIDI port */ 1458c2ecf20Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_OSS_SYNTH 1 /* OSS synth port */ 1468c2ecf20Sopenharmony_ci#define SNDRV_EMUX_PORT_MODE_OSS_MIDI 2 /* OSS multi channel synth port */ 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* 1498c2ecf20Sopenharmony_ci * A structure to keep track of each hardware voice 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_cistruct snd_emux_voice { 1528c2ecf20Sopenharmony_ci int ch; /* Hardware channel number */ 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci int state; /* status */ 1558c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_OFF 0x00 /* Not playing, and inactive */ 1568c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_ON 0x01 /* Note on */ 1578c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_RELEASED (0x02|SNDRV_EMUX_ST_ON) /* Note released */ 1588c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_SUSTAINED (0x04|SNDRV_EMUX_ST_ON) /* Note sustained */ 1598c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_STANDBY (0x08|SNDRV_EMUX_ST_ON) /* Waiting to be triggered */ 1608c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_PENDING (0x10|SNDRV_EMUX_ST_ON) /* Note will be released */ 1618c2ecf20Sopenharmony_ci#define SNDRV_EMUX_ST_LOCKED 0x100 /* Not accessible */ 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci unsigned int time; /* An allocation time */ 1648c2ecf20Sopenharmony_ci unsigned char note; /* Note currently assigned to this voice */ 1658c2ecf20Sopenharmony_ci unsigned char key; 1668c2ecf20Sopenharmony_ci unsigned char velocity; /* Velocity of current note */ 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci struct snd_sf_zone *zone; /* Zone assigned to this note */ 1698c2ecf20Sopenharmony_ci void *block; /* sample block pointer (optional) */ 1708c2ecf20Sopenharmony_ci struct snd_midi_channel *chan; /* Midi channel for this note */ 1718c2ecf20Sopenharmony_ci struct snd_emux_port *port; /* associated port */ 1728c2ecf20Sopenharmony_ci struct snd_emux *emu; /* assigned root info */ 1738c2ecf20Sopenharmony_ci void *hw; /* hardware pointer (emu8000 or emu10k1) */ 1748c2ecf20Sopenharmony_ci unsigned long ontime; /* jiffies at note triggered */ 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* Emu8k/Emu10k1 registers */ 1778c2ecf20Sopenharmony_ci struct soundfont_voice_info reg; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci /* additional registers */ 1808c2ecf20Sopenharmony_ci int avol; /* volume attenuation */ 1818c2ecf20Sopenharmony_ci int acutoff; /* cutoff target */ 1828c2ecf20Sopenharmony_ci int apitch; /* pitch offset */ 1838c2ecf20Sopenharmony_ci int apan; /* pan/aux pair */ 1848c2ecf20Sopenharmony_ci int aaux; 1858c2ecf20Sopenharmony_ci int ptarget; /* pitch target */ 1868c2ecf20Sopenharmony_ci int vtarget; /* volume target */ 1878c2ecf20Sopenharmony_ci int ftarget; /* filter target */ 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/* 1928c2ecf20Sopenharmony_ci * update flags (can be combined) 1938c2ecf20Sopenharmony_ci */ 1948c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_VOLUME (1<<0) 1958c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_PITCH (1<<1) 1968c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_PAN (1<<2) 1978c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_FMMOD (1<<3) 1988c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_TREMFREQ (1<<4) 1998c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_FM2FRQ2 (1<<5) 2008c2ecf20Sopenharmony_ci#define SNDRV_EMUX_UPDATE_Q (1<<6) 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci#ifdef SNDRV_EMUX_USE_RAW_EFFECT 2048c2ecf20Sopenharmony_ci/* 2058c2ecf20Sopenharmony_ci * effect table 2068c2ecf20Sopenharmony_ci */ 2078c2ecf20Sopenharmony_cistruct snd_emux_effect_table { 2088c2ecf20Sopenharmony_ci /* Emu8000 specific effects */ 2098c2ecf20Sopenharmony_ci short val[EMUX_NUM_EFFECTS]; 2108c2ecf20Sopenharmony_ci unsigned char flag[EMUX_NUM_EFFECTS]; 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci#endif /* SNDRV_EMUX_USE_RAW_EFFECT */ 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci/* 2168c2ecf20Sopenharmony_ci * prototypes - interface to Emu10k1 and Emu8k routines 2178c2ecf20Sopenharmony_ci */ 2188c2ecf20Sopenharmony_ciint snd_emux_new(struct snd_emux **remu); 2198c2ecf20Sopenharmony_ciint snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name); 2208c2ecf20Sopenharmony_ciint snd_emux_free(struct snd_emux *emu); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/* 2238c2ecf20Sopenharmony_ci * exported functions 2248c2ecf20Sopenharmony_ci */ 2258c2ecf20Sopenharmony_civoid snd_emux_terminate_all(struct snd_emux *emu); 2268c2ecf20Sopenharmony_civoid snd_emux_lock_voice(struct snd_emux *emu, int voice); 2278c2ecf20Sopenharmony_civoid snd_emux_unlock_voice(struct snd_emux *emu, int voice); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci#endif /* __SOUND_EMUX_SYNTH_H */ 230