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

📄 awe_wave.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * sound/awe_wave.c * * The low level driver for the AWE32/Sound Blaster 32 wave table synth. *   version 0.2.0a; Oct. 30, 1996 * * (C) 1996 Takashi Iwai * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//* if you're using obsolete VoxWare 3.0.x on Linux 1.2.x (or FreeBSD), * uncomment the following line */#define AWE_OBSOLETE_VOXWARE#ifdef AWE_OBSOLETE_VOXWARE#ifdef __FreeBSD__#  include <i386/isa/sound/sound_config.h>#else#  include "sound_config.h"#endif#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32)#define CONFIG_AWE32_SYNTH#endif#else /* AWE_OBSOLETE_VOXWARE */#include "../sound_config.h"#endif /* AWE_OBSOLETE_VOXWARE *//*----------------------------------------------------------------* * compile condition *----------------------------------------------------------------*//* initialize FM passthrough even without extended RAM *//*#define AWE_ALWAYS_INIT_FM*//* debug on */#define AWE_DEBUG_ON/* verify checksum for uploading samples */#define AWE_CHECKSUM_DATA#define AWE_CHECKSUM_MEMORY/* disable interruption during sequencer operation *//*#define AWE_NEED_DISABLE_INTR*//* use buffered access to user wave data */#define AWE_USE_BUFFERED_IO#ifdef linux/* i tested this only on my linux */#define INLINE  __inline__#else#define INLINE /**/#endif/*----------------------------------------------------------------*/#ifdef CONFIG_AWE32_SYNTH#include <i386/isa/sound/awe_hw.h>#include <i386/isa/sound/awe_voice.h>#ifdef AWE_OBSOLETE_VOXWARE#ifdef __FreeBSD__#define SEQUENCER_C#endif#include <i386/isa/sound/tuning.h>#else#include "../tuning.h"#endif#ifdef linux#  include <linux/ultrasound.h>#elif defined(__FreeBSD__)#  include <machine/ultrasound.h>#endif/*---------------------------------------------------------------- * debug message *----------------------------------------------------------------*/#ifdef AWE_DEBUG_ONstatic int debug_mode = 0;#define DEBUG(LVL,XXX)	{if (debug_mode > LVL) { XXX; }}#define ERRMSG(XXX)	{if (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 *----------------------------------------------------------------*//* bank record */typedef struct _awe_voice_list {	unsigned char bank, instr;	awe_voice_info v;	struct _awe_voice_list *next_instr;	struct _awe_voice_list *next_bank;} awe_voice_list;/* sample and information table */static awe_sample_info *samples;static awe_voice_list *infos;#define AWE_MAX_PRESETS		256#define AWE_DEFAULT_BANK	0/* preset table index */static awe_voice_list *preset_table[AWE_MAX_PRESETS];/*---------------------------------------------------------------- * voice table *----------------------------------------------------------------*/#define AWE_FX_BYTES	((AWE_FX_END+7)/8)typedef struct _voice_info {	int state;		/* status (on = 1, off = 0) */	int note;		/* midi key (0-127) */	int velocity;		/* midi velocity (0-127) */	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) */	/* EMU8000 parameters */	int apitch;		/* pitch parameter */	int avol;		/* volume parameter */	/* instrument parameters */	int bank;		/* current tone bank */	int instr;		/* current program */	awe_voice_list *vrec;	awe_voice_info *sample;	/* channel effects */	unsigned char fx_flags[AWE_FX_BYTES];	short fx[AWE_FX_END];} voice_info;static voice_info voices[AWE_MAX_VOICES];/*---------------------------------------------------------------- * global variables *----------------------------------------------------------------*//* awe32 base address (overwritten at initialization) */static int awe_base = 0;/* memory byte size (overwritten at initialization) */static long awe_mem_size = 0;/* maximum channels for playing */static int awe_max_voices = AWE_MAX_VOICES;static long free_mem_ptr = 0;		/* free word byte size */static int free_info = 0;		/* free info tables */static int last_info = 0;		/* last loaded info index */static int free_sample = 0;		/* free sample tables */static int last_sample = 0;		/* last loaded sample index */static int loaded_once = 0;		/* samples are loaded after init? */static unsigned short current_sf_id = 0;	/* internal id */static int reverb_mode = 0;		/* reverb mode */static int chorus_mode = 0;		/* chorus mode */static unsigned short init_atten = 32;  /* 12dB */static int awe_present = 0;		/* awe device present? */static int awe_busy = 0;		/* awe device opened? */static int awe_gus_bank = AWE_DEFAULT_BANK;	/* GUS default bank number */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) */	AWE_MAX_INFOS		/* instr_bank_size */};static struct voice_alloc_info *voice_alloc;	/* set at initialization *//*---------------------------------------------------------------- * function prototypes *----------------------------------------------------------------*/#ifndef AWE_OBSOLETE_VOXWAREstatic int awe_check_port(void);static void awe_request_region(void);static void awe_release_region(void);#endifstatic void awe_reset_samples(void);/* emu8000 chip i/o access */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 long data);static unsigned short awe_peek(unsigned short cmd, unsigned short port);static unsigned long awe_peek_dw(unsigned short cmd, unsigned short port);static void awe_wait(unsigned short delay);/* initialize emu8000 chip */static void awe_initialize(void);/* set voice parameters */static void awe_init_voice_info(awe_voice_info *vp);static void awe_init_voice_parm(awe_voice_parm *pp);static 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);/* 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);/* calculate voice parameters */static void awe_set_pitch(int voice);static void awe_set_volume(int voice);static void awe_set_pan(int voice, int forced);static void awe_fx_fmmod(int voice);static void awe_fx_tremfrq(int voice);static void awe_fx_fm2frq2(int voice);static void awe_fx_cutoff(int voice);static void awe_fx_initpitch(int voice);static void awe_calc_pitch(int voice);static void awe_calc_pitch_from_freq(int voice, int freq);static void awe_calc_volume(int voice);static void awe_voice_init(int voice, int inst_only);/* 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 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 int awe_patchmgr(int dev, struct patmgr_info *rec);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);/* hardware controls */static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);/* voice search */static awe_voice_info *awe_search_voice(int voice, int note);static awe_voice_list *awe_search_instr(int bank, int preset);/* load / remove patches */static void awe_check_loaded(void);static int awe_load_info(awe_patch_info *patch, const char *addr);static int awe_load_data(awe_patch_info *patch, const char *addr);static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);static int awe_write_wave_data(const char *addr, long offset, int size);static awe_voice_list *awe_get_removed_list(awe_voice_list *curp);static void awe_remove_samples(void);static short awe_set_sample(awe_voice_info *vp);/* 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(void);static void awe_init_fm(void);static int awe_open_dram_for_write(int offset);static int awe_open_dram_for_read(int offset);static void awe_open_dram_for_check(void);static void awe_close_dram(void);static void awe_close_dram_for_read(void);static void awe_write_dram(unsigned short c);static int awe_detect(void);static int awe_check_dram(void);static void awe_set_chorus_mode(int mode);static void awe_set_reverb_mode(int mode);#ifdef AWE_OBSOLETE_VOXWARE#define awe_check_port()	0	/* always false */#define awe_request_region()	/* nothing */#define awe_release_region()	/* nothing */#else /* AWE_OBSOLETE_VOXWARE *//* the following macros are osbolete */#define PERMANENT_MALLOC(type,var,size,memptr) \	var = (type)(sound_mem_blocks[sound_nblocks++] = vmalloc(size))#define RET_ERROR(err)			-err#endif /* AWE_OBSOLETE_VOXWARE */#ifdef AWE_NEED_DISABLE_INTR#define DECL_INTR_FLAGS(x)	unsigned long x#else#undef DISABLE_INTR#undef RESTORE_INTR#define DECL_INTR_FLAGS(x) /**/#define DISABLE_INTR(x) /**/#define RESTORE_INTR(x) /**/#endif/* macros for Linux and FreeBSD compatibility */#undef OUTW#undef COPY_FROM_USER#undef GET_BYTE_FROM_USER#undef GET_SHORT_FROM_USER#undef IOCTL_TO_USER  #ifdef linux#  define NO_DATA_ERR                 ENODATA#  define OUTW(data, addr)            outw(data, addr)#  define COPY_FROM_USER(target, source, offs, count) \              memcpy_fromfs( ((caddr_t)(target)),(source)+(offs),(count) )#  define GET_BYTE_FROM_USER(target, addr, offs)      \              *((char  *)&(target)) = get_fs_byte( (addr)+(offs) )#  define GET_SHORT_FROM_USER(target, addr, offs)     \              *((short *)&(target)) = get_fs_word( (addr)+(offs) )#  define IOCTL_TO_USER(target, offs, source, count)  \              memcpy_tofs  ( ((caddr_t)(target)),(source)+(offs),(count) )#  define BZERO(target,len)                           \              memset( (caddr_t)target, '\0', len )#  define MEMCPY(dst,src,len) \              memcpy((caddr_t)dst, (caddr_t)src, len)#elif defined(__FreeBSD__)#  define NO_DATA_ERR                 EINVAL#  define OUTW(data, addr)            outw(addr, data)#  define COPY_FROM_USER(target, source, offs, count) \              uiomove( ((caddr_t)(target)),(count),((struct uio *)(source)) )#  define GET_BYTE_FROM_USER(target, addr, offs)      \              uiomove( ((char*)&(target)), 1, ((struct uio *)(addr)) )#  define GET_SHORT_FROM_USER(target, addr, offs)     \              uiomove( ((char*)&(target)), 2, ((struct uio *)(addr)) )#  define IOCTL_TO_USER(target, offs, source, count)  \              memcpy( &((target)[offs]), (source), (count) )#  define BZERO(target,len)                           \              bzero( (caddr_t)target, len )#  define MEMCPY(dst,src,len) \              bcopy((caddr_t)src, (caddr_t)dst, len)#endif/*---------------------------------------------------------------- * synth operation table *----------------------------------------------------------------*/static struct synth_operations awe_operations ={	&awe_info,	0,	SYNTH_TYPE_SAMPLE,	SAMPLE_TYPE_AWE32,	awe_open,	awe_close,	awe_ioctl,	awe_kill_note,	awe_start_note,	awe_set_instr,	awe_reset,	awe_hw_control,	awe_load_patch,	awe_aftertouch,	awe_controller,	awe_panning,	awe_volume_method,	awe_patchmgr,	awe_bender,	awe_alloc,	awe_setup_voice};/*================================================================ * attach / unload interface *================================================================*/#ifdef AWE_OBSOLETE_VOXWARElong attach_awe_obsolete(long mem_start, struct address_info *hw_config)#elseint attach_awe(void)#endif{	/* check presence of AWE32 card */	if (! awe_detect()) {		printk("AWE32: not detected\n");		return 0;	}	/* check AWE32 ports are available */	if (awe_check_port()) {		printk("AWE32: I/O area already used.\n");		return 0;	}	/* allocate sample tables */	PERMANENT_MALLOC(awe_sample_info *, samples,			 AWE_MAX_SAMPLES * sizeof(awe_sample_info), mem_start);	PERMANENT_MALLOC(awe_voice_list *, infos,			 AWE_MAX_INFOS * sizeof(awe_voice_list), mem_start);	if (samples == NULL || infos == NULL) {		printk("AWE32: can't allocate sample tables\n");		return 0;	}	if (num_synths >= MAX_SYNTH_DEV)		printk("AWE32 Error: too many synthesizers\n");	else {		voice_alloc = &awe_operations.alloc;		voice_alloc->max_voice = awe_max_voices;		synth_devs[num_synths++] = &awe_operations;	}	/* reserve I/O ports for awedrv */	awe_request_region();	/* clear all samples */	awe_reset_samples();	/* intialize AWE32 hardware */	awe_initialize();#if 0	/* Drivers shouldn't be this chatty by default */	printk("<AWE32 SynthCard (%dk)>\n", (int)awe_mem_size/1024);#endif	sprintf(awe_info.name, "AWE32 Synth (%dk)", (int)awe_mem_size/1024);	/* set reverb & chorus modes */	awe_set_reverb_mode(reverb_mode);	awe_set_chorus_mode(chorus_mode);	awe_present = 1;#ifdef AWE_OBSOLETE_VOXWARE	return mem_start;#else	return 1;#endif}void unload_awe(void){	if (awe_present) {		awe_reset_samples();

⌨️ 快捷键说明

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