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

📄 drv_ultra.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	MikMod sound library	(c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for	complete list.	This library is free software; you can redistribute it and/or modify	it under the terms of the GNU Library 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 Library General Public License for more details.	You should have received a copy of the GNU Library General Public	License along with this library; if not, write to the Free Software	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA	02111-1307, USA.*//*==============================================================================  $Id: drv_ultra.c,v 1.4 2004/02/05 17:34:49 raph Exp $  Driver for Gravis Ultrasound cards using libGUS.  A subset of libGUS is provided for DOS/DJGPP and OS/2==============================================================================*//*	Written by Andy Lo A Foe <andy@alsa-project.org>	Updated to work with later versions of both the ultrasound driver and	libmikmod by C. Ray C. <crayc@pyro.net>	Major fixes by Andrew Zabolotny <bit@eltech.ru>	+ Ported to OS/2 and DOS.	+ Eight-bit samples are not converted to 16-bit anymore.	+ Samples are no longer kept in normal memory.	+ Removed sample 'unclick' logic... libGUS does unclick internally.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "mikmod_internals.h"#ifdef DRV_ULTRA#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_MEMORY_H#include <memory.h>#endif#ifdef MIKMOD_DYNAMIC#include <dlfcn.h>#endif#include <errno.h>#include <stdlib.h>#include <string.h>#include <libgus.h>/* DOS/DJGPP and OS/2 libGUS'es have gus_get_voice_status() */#if defined (__EMX__) || defined (__DJGPP__)#define HAVE_VOICE_STATUS#else#include <time.h>#endif#ifdef MIKMOD_DYNAMIC/* runtime link with libgus */static int (*libgus_cards) (void);static int (*libgus_close) (int);static int (*libgus_do_flush) (void);static void (*libgus_do_tempo) (unsigned int);static void (*libgus_do_voice_frequency) (unsigned char, unsigned int);static void (*libgus_do_voice_pan) (unsigned char, unsigned short);static void (*libgus_do_voice_start) (unsigned char, unsigned int,									  unsigned int, unsigned short,									  unsigned short);static void (*libgus_do_voice_start_position) (unsigned char, unsigned int,											   unsigned int, unsigned short,											   unsigned short, unsigned int);static void (*libgus_do_voice_stop) (unsigned char, unsigned char);static void (*libgus_do_voice_volume) (unsigned char, unsigned short);static void (*libgus_do_wait) (unsigned int);static int (*libgus_get_handle) (void);static int (*libgus_info) (gus_info_t *, int);static int (*libgus_memory_alloc) (gus_instrument_t *);static int (*libgus_memory_free) (gus_instrument_t *);static int (*libgus_memory_free_size) (void);static int (*libgus_memory_pack) (void);static int (*libgus_open) (int, size_t, int);static int (*libgus_queue_flush) (void);static int (*libgus_queue_read_set_size) (int);static int (*libgus_queue_write_set_size) (int);static int (*libgus_reset) (int, unsigned int);static int (*libgus_select) (int);static int (*libgus_timer_start) (void);static int (*libgus_timer_stop) (void);static int (*libgus_timer_tempo) (int);static void *libgus = NULL;#ifndef HAVE_RTLD_GLOBAL#define RTLD_GLOBAL 0#endif#else/* compile-time link with libgus */#define libgus_cards					gus_cards#define libgus_close					gus_close#define libgus_do_flush					gus_do_flush#define libgus_do_tempo					gus_do_tempo#define libgus_do_voice_frequency		gus_do_voice_frequency#define libgus_do_voice_pan				gus_do_voice_pan#define libgus_do_voice_start			gus_do_voice_start#define libgus_do_voice_start_position	gus_do_voice_start_position#define libgus_do_voice_stop            gus_do_voice_stop#define libgus_do_voice_volume			gus_do_voice_volume#define libgus_do_wait					gus_do_wait#define libgus_get_handle				gus_get_handle#define libgus_info						gus_info#define libgus_memory_alloc				gus_memory_alloc#define libgus_memory_free				gus_memory_free#define libgus_memory_free_size			gus_memory_free_size#define libgus_memory_pack				gus_memory_pack#define libgus_open						gus_open#define libgus_queue_flush				gus_queue_flush#define libgus_queue_read_set_size		gus_queue_read_set_size#define libgus_queue_write_set_size		gus_queue_write_set_size#define libgus_reset					gus_reset#define libgus_select					gus_select#define libgus_timer_start				gus_timer_start#define libgus_timer_stop				gus_timer_stop#define libgus_timer_tempo				gus_timer_tempo#endif#define GUS_SAMPLES			256 /* Max. GUS samples loadable */#define GUS_CHANNELS		32	/* Max. GUS channels available */#define SIZE_OF_SEQBUF		(8 * 1024)	/* Size of the sequence buffer */#define ULTRA_PAN_MIDDLE	(16383 >> 1)	/* Middle balance position */#define	CH_FREQ 1#define CH_VOL  2#define	CH_PAN  4/*	This structure holds the current state of a GUS voice channel. */typedef struct GUS_VOICE {	UBYTE kick;	UBYTE active;	UWORD flags;	SWORD handle;	ULONG start;	ULONG size;	ULONG reppos;	ULONG repend;	ULONG frq;	int vol;	int decvol;	int pan;	int changes;#ifndef HAVE_VOICE_STATUS	time_t started;#endif} GUS_VOICE;/* Global declarations follow */static SAMPLE *samples[GUS_SAMPLES];	/* sample handles */static GUS_VOICE voices[GUS_CHANNELS];	/* channel status */static int ultra_dev = 0;	/* GUS index, if more than one card */static int ultra_handle = -1;	/* GUS handle */static int ultra_fd = -1;	/* GUS file descriptor */#ifdef MIKMOD_DYNAMICstatic BOOL Ultra_Link(void){	if (libgus)		return 0;	/* load libgus.so */	libgus = dlopen("libgus.so", RTLD_LAZY | RTLD_GLOBAL);	if (!libgus)		return 1;	/* resolve function references */#define IMPORT_SYMBOL(x) \	if (!(lib##x = dlsym(libgus, #x))) return 1	IMPORT_SYMBOL(gus_cards);	IMPORT_SYMBOL(gus_close);	IMPORT_SYMBOL(gus_do_flush);	IMPORT_SYMBOL(gus_do_tempo);	IMPORT_SYMBOL(gus_do_voice_frequency);	IMPORT_SYMBOL(gus_do_voice_pan);	IMPORT_SYMBOL(gus_do_voice_start);	IMPORT_SYMBOL(gus_do_voice_start_position);	IMPORT_SYMBOL(gus_do_voice_stop);	IMPORT_SYMBOL(gus_do_voice_volume);	IMPORT_SYMBOL(gus_do_wait);	IMPORT_SYMBOL(gus_get_handle);	IMPORT_SYMBOL(gus_info);	IMPORT_SYMBOL(gus_memory_alloc);	IMPORT_SYMBOL(gus_memory_free);	IMPORT_SYMBOL(gus_memory_free_size);	IMPORT_SYMBOL(gus_memory_pack);	IMPORT_SYMBOL(gus_open);	IMPORT_SYMBOL(gus_queue_flush);	IMPORT_SYMBOL(gus_queue_read_set_size);	IMPORT_SYMBOL(gus_queue_write_set_size);	IMPORT_SYMBOL(gus_reset);	IMPORT_SYMBOL(gus_select);	IMPORT_SYMBOL(gus_timer_start);	IMPORT_SYMBOL(gus_timer_stop);	IMPORT_SYMBOL(gus_timer_tempo);#undef IMPORT_SYMBOL	return 0;}static void Ultra_Unlink(void){	libgus_cards = NULL;	libgus_close = NULL;	libgus_do_flush = NULL;	libgus_do_tempo = NULL;	libgus_do_voice_frequency = NULL;	libgus_do_voice_pan = NULL;	libgus_do_voice_start = NULL;	libgus_do_voice_start_position = NULL;	libgus_do_voice_stop = NULL;	libgus_do_voice_volume = NULL;	libgus_do_wait = NULL;	libgus_get_handle = NULL;	libgus_info = NULL;	libgus_memory_alloc = NULL;	libgus_memory_free = NULL;	libgus_memory_free_size = NULL;	libgus_memory_pack = NULL;	libgus_open = NULL;	libgus_queue_flush = NULL;	libgus_queue_read_set_size = NULL;	libgus_queue_write_set_size = NULL;	libgus_reset = NULL;	libgus_select = NULL;	libgus_timer_start = NULL;	libgus_timer_stop = NULL;	libgus_timer_tempo = NULL;	if (libgus) {		dlclose(libgus);		libgus = NULL;	}}#endifstatic void Ultra_CommandLine(CHAR *cmdline){	CHAR *ptr = MD_GetAtom("card", cmdline, 0);		if (ptr) {		int buf = atoi(ptr);				if (buf >= 0 && buf <= 8)			ultra_dev = buf;		free(ptr);	}#ifdef __DJGPP__	if ((ptr = MD_GetAtom("dma", cmdline, 0))) {		gus_dma_usage (atoi(ptr));		free(ptr);	}#endif}/* Checks for the presence of GUS cards */static BOOL Ultra_IsThere(void){	int retval;#ifdef MIKMOD_DYNAMIC	if (Ultra_Link())		return 0;#endif	retval = libgus_cards()? 1 : 0;#ifdef MIKMOD_DYNAMIC	Ultra_Unlink();#endif	return retval;}/* Load a new sample directly into GUS DRAM and return a handle */static SWORD Ultra_SampleLoad(struct SAMPLOAD *sload){	int handle;	SAMPLE *s = sload->sample;	gus_instrument_t instrument;	gus_layer_t layer;	gus_wave_t wave;	unsigned char *buffer;	unsigned int length, loopstart, loopend;	/* Find empty slot to put sample in */	for (handle = 0; handle < GUS_SAMPLES; handle++)		if (!samples[handle])			break;	if (handle == GUS_SAMPLES) {		_mm_errno = MMERR_OUT_OF_HANDLES;		return -1;	}	/* Fill an gus_instrument_t structure and feed it to libgus. We can	   download 8 and 16 bit, both signed and unsigned samples into GUS, so	   don't bother much about formats here. */	/* convert position/length data from samples to bytes */	length = s->length;	loopstart = s->loopstart;	loopend = s->loopend ? s->loopend : length;	/* sanity checks */	if (loopend > length)		loopend = length;	if (loopstart > loopend)		loopstart = loopend;	if (s->flags & SF_16BITS) {		length <<= 1;		loopstart <<= 1;		loopend <<= 1;	}	/* Load sample into normal memory */	if (!(buffer = _mm_malloc(length))) {		_mm_errno = MMERR_SAMPLE_TOO_BIG;		return -1;	}	if (SL_Load(buffer, sload, s->length)) {		free(buffer);		return -1;	}	samples[handle] = s;	memset(&wave, 0, sizeof(wave));	memset(&layer, 0, sizeof(layer));	memset(&instrument, 0, sizeof(instrument));	wave.format =		((s->flags & SF_SIGNED) ? 0 : GUS_WAVE_INVERT) |		((s->flags & SF_16BITS) ? GUS_WAVE_16BIT : 0) |		((s->flags & SF_DELTA ) ? GUS_WAVE_DELTA : 0) |		((s->flags & SF_LOOP  ) ? GUS_WAVE_LOOP  : 0) |		((s->flags & SF_BIDI  ) ? GUS_WAVE_BIDIR : 0);	wave.begin.ptr = buffer;	wave.loop_start = loopstart << 4;	wave.loop_end = loopend << 4;	wave.size = length;	layer.wave = &wave;	instrument.mode = layer.mode = wave.mode = GUS_INSTR_SIMPLE;	instrument.number.instrument = handle;	instrument.info.layer = &layer;	/* Download the sample to GUS RAM */	if (libgus_memory_alloc(&instrument)) {		free(buffer);		_mm_errno = MMERR_SAMPLE_TOO_BIG;		return -1;	}	free(buffer);	return handle;}/* Discards a sample from the GUS memory and mark handle as free */static void Ultra_SampleUnload(SWORD handle){	gus_instrument_t instrument;	if (handle >= GUS_SAMPLES || handle < 0 || !samples[handle])		return;	memset(&instrument, 0, sizeof(instrument));	instrument.mode = GUS_INSTR_SIMPLE;	instrument.number.instrument = handle;	libgus_memory_free(&instrument);	samples[handle] = NULL;}/* Reports available sample space */static ULONG Ultra_SampleSpace(void){	libgus_memory_pack();	return (libgus_memory_free_size());}/* Reports the size of a sample */static ULONG Ultra_SampleLength(SAMPLE *s){	if (!s)		return 0;	if (s->flags & SF_16BITS)		return ((s->length << 1) + 31) & ~31;	else		return ( s->length       + 15) & ~15;}/* Initializes the driver */static BOOL Ultra_Init_internal(void){	gus_info_t info;	/* Open the GUS card */	if ((ultra_handle = libgus_open(ultra_dev, SIZE_OF_SEQBUF, 0)) < 0) {		_mm_errno =		  (errno == ENOMEM) ? MMERR_OUT_OF_MEMORY : MMERR_INVALID_DEVICE;		return 1;	}	libgus_select(ultra_handle);	ultra_fd = libgus_get_handle();	/* Get card information */	libgus_info(&info, 0);

⌨️ 快捷键说明

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