From 224a033252bba46c5c8b5df625f5e781ca138f48 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 30 Oct 2007 11:49:22 +0100 Subject: [ALSA] opl3 - Use hwdep for patch loading Use the hwdep device for loading OPL2/3 patch data instead of the messy sequencer instrument layer. Due to this change, the sbiload program should be updated, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- include/sound/asound_fm.h | 19 ++++++++++++++++ include/sound/opl3.h | 58 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 3 deletions(-) (limited to 'include/sound') diff --git a/include/sound/asound_fm.h b/include/sound/asound_fm.h index 8fbcab7cc73..c2a4b967d5b 100644 --- a/include/sound/asound_fm.h +++ b/include/sound/asound_fm.h @@ -104,6 +104,8 @@ struct snd_dm_fm_params { #define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int) /* for OPL3 only */ #define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int) +/* SBI patch management */ +#define SNDRV_DM_FM_IOCTL_CLEAR_PATCHES _IO ('H', 0x40) #define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 #define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 @@ -112,4 +114,21 @@ struct snd_dm_fm_params { #define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 #define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 +/* + * Patch Record - fixed size for write + */ + +#define FM_KEY_SBI "SBI\032" +#define FM_KEY_2OP "2OP\032" +#define FM_KEY_4OP "4OP\032" + +struct sbi_patch { + unsigned char prog; + unsigned char bank; + char key[4]; + char name[25]; + char extension[7]; + unsigned char data[32]; +}; + #endif /* __SOUND_ASOUND_FM_H */ diff --git a/include/sound/opl3.h b/include/sound/opl3.h index 1d14b3f8239..7ee865d6236 100644 --- a/include/sound/opl3.h +++ b/include/sound/opl3.h @@ -63,7 +63,7 @@ #include "seq_oss_legacy.h" #endif #include "seq_device.h" -#include "ainstr_fm.h" +#include "asound_fm.h" /* * Register numbers for the global registers @@ -239,6 +239,47 @@ struct snd_opl3; +/* + * Instrument record, aka "Patch" + */ + +/* FM operator */ +struct fm_operator { + unsigned char am_vib; + unsigned char ksl_level; + unsigned char attack_decay; + unsigned char sustain_release; + unsigned char wave_select; +} __attribute__((packed)); + +/* Instrument data */ +struct fm_instrument { + struct fm_operator op[4]; + unsigned char feedback_connection[2]; + unsigned char echo_delay; + unsigned char echo_atten; + unsigned char chorus_spread; + unsigned char trnsps; + unsigned char fix_dur; + unsigned char modes; + unsigned char fix_key; +}; + +/* type */ +#define FM_PATCH_OPL2 0x01 /* OPL2 2 operators FM instrument */ +#define FM_PATCH_OPL3 0x02 /* OPL3 4 operators FM instrument */ + +/* Instrument record */ +struct fm_patch { + unsigned char prog; + unsigned char bank; + unsigned char type; + struct fm_instrument inst; + char name[24]; + struct fm_patch *next; +}; + + /* * A structure to keep track of each hardware voice */ @@ -297,8 +338,8 @@ struct snd_opl3 { struct snd_midi_channel_set * oss_chset; #endif - struct snd_seq_kinstr_ops fm_ops; - struct snd_seq_kinstr_list *ilist; +#define OPL3_PATCH_HASH_SIZE 32 + struct fm_patch *patch_table[OPL3_PATCH_HASH_SIZE]; struct snd_opl3_voice voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */ int use_time; /* allocation counter */ @@ -333,8 +374,19 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device, int snd_opl3_open(struct snd_hwdep * hw, struct file *file); int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg); +long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, + loff_t *offset); int snd_opl3_release(struct snd_hwdep * hw, struct file *file); void snd_opl3_reset(struct snd_opl3 * opl3); +int snd_opl3_load_patch(struct snd_opl3 *opl3, + int prog, int bank, int type, + const char *name, + const unsigned char *ext, + const unsigned char *data); +struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank, + int create_patch); +void snd_opl3_clear_patches(struct snd_opl3 *opl3); + #endif /* __SOUND_OPL3_H */ -- cgit v1.2.3