⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 awe_wave.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * sound/awe_wave.c * * The low level driver for the AWE32/SB32/AWE64 wave table synth. *   version 0.4.4; Jan. 4, 2000 * * Copyright (C) 1996-2000 Takashi Iwai * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/awe_voice.h>#include <linux/config.h>#include <linux/init.h>#include <linux/module.h>#include <linux/string.h>#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE#include <linux/isapnp.h>#endif#include "sound_config.h"#include "awe_wave.h"#include "awe_hw.h"#ifdef AWE_HAS_GUS_COMPATIBILITY#include "tuning.h"#include <linux/ultrasound.h>#endif/* * debug message */#ifdef AWE_DEBUG_ON#define DEBUG(LVL,XXX)	{if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}#define ERRMSG(XXX)	{if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}#define FATALERR(XXX)	XXX#else#define DEBUG(LVL,XXX) /**/#define ERRMSG(XXX)	XXX#define FATALERR(XXX)	XXX#endif/* * bank and voice record */typedef struct _sf_list sf_list;typedef struct _awe_voice_list awe_voice_list;typedef struct _awe_sample_list awe_sample_list;/* soundfont record */struct _sf_list {	unsigned short sf_id;	/* id number */	unsigned short type;	/* lock & shared flags */	int num_info;		/* current info table index */	int num_sample;		/* current sample table index */	int mem_ptr;		/* current word byte pointer */	awe_voice_list *infos, *last_infos;	/* instruments */	awe_sample_list *samples, *last_samples;	/* samples */#ifdef AWE_ALLOW_SAMPLE_SHARING	sf_list *shared;	/* shared list */	unsigned char name[AWE_PATCH_NAME_LEN];	/* sharing id */#endif	sf_list *next, *prev;};/* instrument list */struct _awe_voice_list {	awe_voice_info v;	/* instrument information */	sf_list *holder;	/* parent sf_list of this record */	unsigned char bank, instr;	/* preset number information */	char type, disabled;	/* type=normal/mapped, disabled=boolean */	awe_voice_list *next;	/* linked list with same sf_id */	awe_voice_list *next_instr;	/* instrument list */	awe_voice_list *next_bank;	/* hash table list */};/* voice list type */#define V_ST_NORMAL	0#define V_ST_MAPPED	1/* sample list */struct _awe_sample_list {	awe_sample_info v;	/* sample information */	sf_list *holder;	/* parent sf_list of this record */	awe_sample_list *next;	/* linked list with same sf_id */};/* sample and information table */static int current_sf_id = 0;	/* current number of fonts */static int locked_sf_id = 0;	/* locked position */static sf_list *sfhead = NULL, *sftail = NULL;	/* linked-lists */#define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)#define awe_free_info() (sftail ? sftail->num_info : 0)#define awe_free_sample() (sftail ? sftail->num_sample : 0)#define AWE_MAX_PRESETS		256#define AWE_DEFAULT_PRESET	0#define AWE_DEFAULT_BANK	0#define AWE_DEFAULT_DRUM	0#define AWE_DRUM_BANK		128#define MAX_LAYERS	AWE_MAX_VOICES/* preset table index */static awe_voice_list *preset_table[AWE_MAX_PRESETS];/* * voice table *//* effects table */typedef	struct FX_Rec { /* channel effects */	unsigned char flags[AWE_FX_END];	short val[AWE_FX_END];} FX_Rec;/* channel parameters */typedef struct _awe_chan_info {	int channel;		/* channel number */	int bank;		/* current tone bank */	int instr;		/* current program */	int bender;		/* midi pitchbend (-8192 - 8192) */	int bender_range;	/* midi bender range (x100) */	int panning;		/* panning (0-127) */	int main_vol;		/* channel volume (0-127) */	int expression_vol;	/* midi expression (0-127) */	int chan_press;		/* channel pressure */	int sustained;		/* sustain status in MIDI */	FX_Rec fx;		/* effects */	FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */} awe_chan_info;/* voice parameters */typedef struct _voice_info {	int state;#define AWE_ST_OFF		(1<<0)	/* no sound */#define AWE_ST_ON		(1<<1)	/* playing */#define AWE_ST_STANDBY		(1<<2)	/* stand by for playing */#define AWE_ST_SUSTAINED	(1<<3)	/* sustained */#define AWE_ST_MARK		(1<<4)	/* marked for allocation */#define AWE_ST_DRAM		(1<<5)	/* DRAM read/write */#define AWE_ST_FM		(1<<6)	/* reserved for FM */#define AWE_ST_RELEASED		(1<<7)	/* released */	int ch;			/* midi channel */	int key;		/* internal key for search */	int layer;		/* layer number (for channel mode only) */	int time;		/* allocated time */	awe_chan_info	*cinfo;	/* channel info */	int note;		/* midi key (0-127) */	int velocity;		/* midi velocity (0-127) */	int sostenuto;		/* sostenuto on/off */	awe_voice_info *sample;	/* assigned voice */	/* EMU8000 parameters */	int apitch;		/* pitch parameter */	int avol;		/* volume parameter */	int apan;		/* panning parameter */	int acutoff;		/* cutoff parameter */	short aaux;		/* aux word */} voice_info;/* voice information */static voice_info voices[AWE_MAX_VOICES];#define IS_NO_SOUND(v)	(voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))#define IS_NO_EFFECT(v)	(voices[v].state != AWE_ST_ON)#define IS_PLAYING(v)	(voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))#define IS_EMPTY(v)	(voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))/* MIDI channel effects information (for hw control) */static awe_chan_info channels[AWE_MAX_CHANNELS];/* * global variables */#ifndef AWE_DEFAULT_BASE_ADDR#define AWE_DEFAULT_BASE_ADDR	0	/* autodetect */#endif#ifndef AWE_DEFAULT_MEM_SIZE#define AWE_DEFAULT_MEM_SIZE	-1	/* autodetect */#endifint io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULEstatic int isapnp = -1;#elsestatic int isapnp = 0;#endifMODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");MODULE_LICENSE("GPL");MODULE_PARM(io, "i");MODULE_PARM_DESC(io, "base i/o port of Emu8000");MODULE_PARM(memsize, "i");MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");MODULE_PARM(isapnp, "i");MODULE_PARM_DESC(isapnp, "use ISAPnP detection");EXPORT_NO_SYMBOLS;/* DRAM start offset */static int awe_mem_start = AWE_DRAM_OFFSET;/* maximum channels for playing */static int awe_max_voices = AWE_MAX_VOICES;static int patch_opened = 0;		/* sample already loaded? */static char atten_relative = FALSE;static short atten_offset = 0;static int awe_present = FALSE;		/* awe device present? */static int awe_busy = FALSE;		/* awe device opened? */static int my_dev = -1;			#define DEFAULT_DRUM_FLAGS	((1 << 9) | (1 << 25))#define IS_DRUM_CHANNEL(c)	(drum_flags & (1 << (c)))#define DRUM_CHANNEL_ON(c)	(drum_flags |= (1 << (c)))#define DRUM_CHANNEL_OFF(c)	(drum_flags &= ~(1 << (c)))static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */static int playing_mode = AWE_PLAY_INDIRECT;#define SINGLE_LAYER_MODE()	(playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)#define MULTI_LAYER_MODE()	(playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)static int current_alloc_time = 0;	/* voice allocation index for channel mode */static struct synth_info awe_info = {	"AWE32 Synth",		/* name */	0,			/* device */	SYNTH_TYPE_SAMPLE,	/* synth_type */	SAMPLE_TYPE_AWE32,	/* synth_subtype */	0,			/* perc_mode (obsolete) */	AWE_MAX_VOICES,		/* nr_voices */	0,			/* nr_drums (obsolete) */	400			/* instr_bank_size */};static struct voice_alloc_info *voice_alloc;	/* set at initialization *//* * function prototypes */static int awe_check_port(void);static void awe_request_region(void);static void awe_release_region(void);static void awe_reset_samples(void);/* emu8000 chip i/o access */static void setup_ports(int p1, int p2, int p3);static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);static unsigned short awe_peek(unsigned short cmd, unsigned short port);static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);static void awe_wait(unsigned short delay);/* initialize emu8000 chip */static int _attach_awe(void);static void _unload_awe(void);static void awe_initialize(void);/* set voice parameters */static void awe_init_ctrl_parms(int init_all);static void awe_init_voice_info(awe_voice_info *vp);static void awe_init_voice_parm(awe_voice_parm *pp);#ifdef AWE_HAS_GUS_COMPATIBILITYstatic int freq_to_note(int freq);static int calc_rate_offset(int Hz);/*static int calc_parm_delay(int msec);*/static int calc_parm_hold(int msec);static int calc_parm_attack(int msec);static int calc_parm_decay(int msec);static int calc_parm_search(int msec, short *table);#endif /* gus compat *//* turn on/off note */static void awe_note_on(int voice);static void awe_note_off(int voice);static void awe_terminate(int voice);static void awe_exclusive_off(int voice);static void awe_note_off_all(int do_sustain);/* calculate voice parameters */typedef void (*fx_affect_func)(int voice, int forced);static void awe_set_pitch(int voice, int forced);static void awe_set_voice_pitch(int voice, int forced);static void awe_set_volume(int voice, int forced);static void awe_set_voice_vol(int voice, int forced);static void awe_set_pan(int voice, int forced);static void awe_fx_fmmod(int voice, int forced);static void awe_fx_tremfrq(int voice, int forced);static void awe_fx_fm2frq2(int voice, int forced);static void awe_fx_filterQ(int voice, int forced);static void awe_calc_pitch(int voice);#ifdef AWE_HAS_GUS_COMPATIBILITYstatic void awe_calc_pitch_from_freq(int voice, int freq);#endifstatic void awe_calc_volume(int voice);static void awe_update_volume(void);static void awe_change_master_volume(short val);static void awe_voice_init(int voice, int init_all);static void awe_channel_init(int ch, int init_all);static void awe_fx_init(int ch);static void awe_send_effect(int voice, int layer, int type, int val);static void awe_modwheel_change(int voice, int value);/* sequencer interface */static int awe_open(int dev, int mode);static void awe_close(int dev);static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg);static int awe_kill_note(int dev, int voice, int note, int velocity);static int awe_start_note(int dev, int v, int note_num, int volume);static int awe_set_instr(int dev, int voice, int instr_no);static int awe_set_instr_2(int dev, int voice, int instr_no);static void awe_reset(int dev);static void awe_hw_control(int dev, unsigned char *event);static int awe_load_patch(int dev, int format, const char *addr,			  int offs, int count, int pmgr_flag);static void awe_aftertouch(int dev, int voice, int pressure);static void awe_controller(int dev, int voice, int ctrl_num, int value);static void awe_panning(int dev, int voice, int value);static void awe_volume_method(int dev, int mode);static void awe_bender(int dev, int voice, int value);static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);static void awe_setup_voice(int dev, int voice, int chn);#define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)/* hardware controls */#ifdef AWE_HAS_GUS_COMPATIBILITYstatic void awe_hw_gus_control(int dev, int cmd, unsigned char *event);#endifstatic void awe_hw_awe_control(int dev, int cmd, unsigned char *event);static void awe_voice_change(int voice, fx_affect_func func);static void awe_sostenuto_on(int voice, int forced);static void awe_sustain_off(int voice, int forced);static void awe_terminate_and_init(int voice, int forced);/* voice search */static int awe_search_key(int bank, int preset, int note);static awe_voice_list *awe_search_instr(int bank, int preset, int note);static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);static void awe_alloc_one_voice(int voice, int note, int velocity);static int awe_clear_voice(void);/* load / remove patches */static int awe_open_patch(awe_patch_info *patch, const char *addr, int count);static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);static int awe_load_info(awe_patch_info *patch, const char *addr, int count);static int awe_remove_info(awe_patch_info *patch, const char *addr, int count);static int awe_load_data(awe_patch_info *patch, const char *addr, int count);static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);static int awe_load_map(awe_patch_info *patch, const char *addr, int count);#ifdef AWE_HAS_GUS_COMPATIBILITYstatic int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);#endif/*static int awe_probe_info(awe_patch_info *patch, const char *addr, int count);*/static int awe_probe_data(awe_patch_info *patch, const char *addr, int count);static sf_list *check_patch_opened(int type, char *name);static int awe_write_wave_data(const char *addr, int offset, awe_sample_list *sp, int channels);static int awe_create_sf(int type, char *name);static void awe_free_sf(sf_list *sf);static void add_sf_info(sf_list *sf, awe_voice_list *rec);static void add_sf_sample(sf_list *sf, awe_sample_list *smp);static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);static void add_info_list(awe_voice_list *rec);static void awe_remove_samples(int sf_id);static void rebuild_preset_list(void);static short awe_set_sample(awe_voice_list *rec);static awe_sample_list *search_sample_index(sf_list *sf, int sample);static int is_identical_holder(sf_list *sf1, sf_list *sf2);#ifdef AWE_ALLOW_SAMPLE_SHARINGstatic int is_identical_name(unsigned char *name, sf_list *p);static int is_shared_sf(unsigned char *name);static int info_duplicated(sf_list *sf, awe_voice_list *rec);#endif /* allow sharing *//* lowlevel functions */static void awe_init_audio(void);static void awe_init_dma(void);static void awe_init_array(void);static void awe_send_array(unsigned short *data);static void awe_tweak_voice(int voice);static void awe_tweak(void);static void awe_init_fm(void);static int awe_open_dram_for_write(int offset, int channels);static void awe_open_dram_for_check(void);static void awe_close_dram(void);/*static void awe_write_dram(unsigned short c);*/static int awe_detect_base(int addr);static int awe_detect(void);static void awe_check_dram(void);static int awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count);static void awe_set_chorus_mode(int mode);static void awe_update_chorus_mode(void);static int awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count);static void awe_set_reverb_mode(int mode);static void awe_update_reverb_mode(void);static void awe_equalizer(int bass, int treble);static void awe_update_equalizer(void);#ifdef CONFIG_AWE32_MIXERstatic void attach_mixer(void);static void unload_mixer(void);#endif#ifdef CONFIG_AWE32_MIDIEMUstatic void attach_midiemu(void);static void unload_midiemu(void);#endif#define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)/* * control parameters */#ifdef AWE_USE_NEW_VOLUME_CALC#define DEF_VOLUME_CALC	TRUE#else#define DEF_VOLUME_CALC	FALSE#endif /* new volume */#define DEF_ZERO_ATTEN		32	/* 12dB below */#define DEF_MOD_SENSE		18#define DEF_CHORUS_MODE		2#define DEF_REVERB_MODE		4#define DEF_BASS_LEVEL		5#define DEF_TREBLE_LEVEL	9static struct CtrlParmsDef {	int value;	int init_each_time;	void (*update)(void);} ctrl_parms[AWE_MD_END] = {	{0,0, NULL}, {0,0, NULL}, /* <-- not used */	{AWE_VERSION_NUMBER, FALSE, NULL},	{TRUE, FALSE, NULL}, /* exclusive */	{TRUE, FALSE, NULL}, /* realpan */	{AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */	{FALSE, TRUE, NULL}, /* keep effect */	{DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */	{FALSE, FALSE, NULL}, /* chn_prior */	{DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */	{AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */	{AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */	{AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */	{FALSE, FALSE, NULL}, /* toggle_drum_bank */	{DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */	{DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */	{DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */	{DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */	{DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */	{0, FALSE, NULL},	/* debug mode */	{FALSE, FALSE, NULL}, /* pan exchange */};static int ctrls[AWE_MD_END];/* * synth operation table

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -