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