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

📄 drv_sam9407.c

📁 wince下著名的视频播放器源码
💻 C
字号:
/*  MikMod sound library	(c) 1998, 1999, 2000 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_sam9407.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $    Driver for the Linux sam9407 driver  ==============================================================================*//*   Written by Gerd Rausch <gerd@alf.gun.de>   Tempo contributions by Xavier Hosxe <xhosxe@cyrano.com>   Released with libmikmod under LGPL license with the author's permission.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "mikmod_internals.h"#ifdef DRV_SAM9407#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <stdlib.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/sam9407.h>/* Backwards compatibility with driver version 0.9.x */#ifndef SAM_MOD_API_VERSION#define SAM_MOD_API_VERSION SAM_API_VERSION#endif#define SAM_NUM_BANKS	256#define SAM_NUM_VOICES	32#define NO_LOOP_SAMPLES	8#define PENDING_PLAY	(1<<0)#define PENDING_STOP	(1<<1)#define PENDING_VOLUME	(1<<2)#define PENDING_FREQ	(1<<3)typedef struct {	BOOL inUse;	ULONG length, loopstart, loopend;	UWORD flags;} Bank;typedef struct {	BOOL playing;	ULONG pending;	SWORD handle;	ULONG start;	ULONG length;	ULONG loopstart;	ULONG repend;	UWORD flags;	ULONG freq;	UWORD vol;	ULONG pan;} Voice;static Bank banks[SAM_NUM_BANKS];static Voice voices[SAM_NUM_VOICES];static int card=0;static int modfd=-1;static void commandLine(CHAR *cmdline){	CHAR *ptr;	if((ptr=MD_GetAtom("card", cmdline, 0))) {		card=atoi(ptr);		free(ptr);	}}static BOOL isPresent(void){	int fd;	char devName[256];	sprintf(devName, "/dev/sam%d_mod", card);	if((fd=open(devName, O_RDWR))>=0) {		close(fd);		return 1;	}	return (errno == EACCES ? 1 : 0);}static ULONG freeSampleSpace(int type){	SamModMemInfo memInfo;	if(ioctl(modfd, SAM_IOC_MOD_MEM_INFO, &memInfo)<0)		return 0;	return memInfo.memFree<<1;}static SWORD sampleLoad(SAMPLOAD *s, int type){	Bank *bankP;	SamModSamples modSamples;	SWORD handle;	SWORD *samples;int rc;	for(handle=0; handle<SAM_NUM_BANKS; handle++)		if(!banks[handle].inUse)			break;	if(handle>=SAM_NUM_BANKS) {		_mm_errno=MMERR_OUT_OF_HANDLES;		return -1;	}	bankP=banks+handle;	bankP->inUse=1;	SL_SampleSigned(s);	SL_Sample8to16(s);	bankP->length=s->sample->length;	bankP->loopstart=s->sample->loopstart;	bankP->loopend=s->sample->loopend ? s->sample->loopend : s->sample->length;	bankP->flags=s->sample->flags;	if(!(samples=(SWORD *)malloc((bankP->length+NO_LOOP_SAMPLES)<<1))) {		bankP->inUse=0;		_mm_errno=MMERR_SAMPLE_TOO_BIG;		return -1;	}	if(SL_Load(samples, s, bankP->length)) {		free(samples);		bankP->inUse=0;		_mm_errno=MMERR_SAMPLE_TOO_BIG;		return -1;	}	if(!(bankP->flags & SF_LOOP)) {		memset(samples+bankP->length, 0, NO_LOOP_SAMPLES);		bankP->loopstart=bankP->length;		bankP->length+=NO_LOOP_SAMPLES;		bankP->loopend=bankP->length-1;	}	modSamples.handle=handle;	modSamples.data=samples;	modSamples.size=bankP->length;	if((rc=ioctl(modfd, SAM_IOC_MOD_SAMPLES_LOAD, &modSamples))<0) {		free(samples);		bankP->inUse=0;		_mm_errno=MMERR_SAMPLE_TOO_BIG;		return -1;	}	free(samples);	return handle;}void sampleUnload(SWORD handle){	unsigned char modHandle;	if(!banks[handle].inUse)		return;	modHandle=handle;	ioctl(modfd, SAM_IOC_MOD_SAMPLES_UNLOAD, &modHandle);	banks[handle].inUse=0;}static ULONG realSampleLength(int type, SAMPLE *s){	if(!s)		return 0;	return s->length<<1;}static BOOL init(void){	int i;	Voice *voiceP;	char devName[256];	SamApiInfo apiInfo;	sprintf(devName, "/dev/sam%d_mod", card);	if((modfd=open(devName, O_RDWR))<0) {		_mm_errno=MMERR_OPENING_AUDIO;		return 1;	}	if(ioctl(modfd, SAM_IOC_API_INFO, &apiInfo)<0 ||	   apiInfo.version!=SAM_MOD_API_VERSION) {		_mm_errno=MMERR_OPENING_AUDIO;		return 1;	}	for(i=0; i<SAM_NUM_VOICES; i++) {		voiceP=voices+i;		voiceP->freq=44100;		voiceP->vol=0xFF;		voiceP->pan=0x80;	}	md_mode&=~(DMODE_SOFT_MUSIC|DMODE_SOFT_SNDFX);	return 0;}static void exitHook(void){	if(modfd>=0) {		close(modfd);		modfd=-1;	}}static BOOL reset(void){	if(ioctl(modfd, SAM_IOC_MOD_RESET)<0)		return 1;	return 0;}static BOOL setNumVoices(void){	return 0;}static BOOL playStart(void){	ioctl(modfd, SAM_IOC_MOD_TIMER_START);	return 0;}static void playStop(void){	ioctl(modfd, SAM_IOC_MOD_POST);	ioctl(modfd, SAM_IOC_MOD_TIMER_STOP);}static void update(void){	static int wait_echo;	static long ticker_idx;	int i;	Voice *voiceP;	SamModEvent event, eventBuf[SAM_NUM_VOICES*10+8], *eventP;	eventP = eventBuf;	for(i=0; i<md_numchn; i++) {		voiceP=voices+i;		if((voiceP->pending & PENDING_STOP) ||		   ((voiceP->pending & PENDING_PLAY) && voiceP->playing)) {			voiceP->playing=0;			eventP->type=SAM_MOD_EVENT_STOP;			eventP->trigger.voice=i;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModTriggerEvent));			eventP->type=SAM_MOD_EVENT_CLOSE;			eventP->trigger.voice=i;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModTriggerEvent));			voiceP->pending&=~PENDING_STOP;		}		if(voiceP->pending & PENDING_PLAY) {			Bank *bankP=banks+voiceP->handle;			eventP->type=SAM_MOD_EVENT_OPEN;			eventP->trigger.voice=i;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModTriggerEvent));			eventP->type=SAM_MOD_EVENT_MEM;			eventP->mem.voice=i;			eventP->mem.handle=voiceP->handle;			eventP->mem.sampleType=SamModSample16Bit;			eventP->mem.loopType=(bankP->flags & SF_BIDI) ? SamModLoopReverse : SamModLoopForward;			eventP->mem.start=voiceP->start;			eventP->mem.loop=bankP->loopstart;			eventP->mem.end=bankP->loopend;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModMemEvent));			eventP->type=SAM_MOD_EVENT_VOL;			eventP->volOut.voice=i;			eventP->volOut.volume=0xFF;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModVolOutEvent));			voiceP->pending|=PENDING_VOLUME|PENDING_FREQ;		}		if(voiceP->pending & PENDING_VOLUME) {			eventP->type=SAM_MOD_EVENT_MAIN;			eventP->volSend.voice=i;			eventP->volSend.left=voiceP->vol*(255-voiceP->pan)/255;			eventP->volSend.right=voiceP->vol*voiceP->pan/255;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModVolSendEvent));			voiceP->pending&=~PENDING_VOLUME;		}		if(voiceP->pending & PENDING_FREQ) {			eventP->type=SAM_MOD_EVENT_PITCH;			eventP->pitch.voice=i;			eventP->pitch.freq=voiceP->freq;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModPitchEvent));			voiceP->pending&=~PENDING_FREQ;		}		if(voiceP->pending & PENDING_PLAY) {			voiceP->playing=1;			eventP->type=SAM_MOD_EVENT_START;			eventP->trigger.voice=i;			eventP=(SamModEvent *)((char *)eventP+sizeof(SamModTriggerEvent));			voiceP->pending&=~PENDING_PLAY;		}	}	eventP->type=SAM_MOD_EVENT_WAIT_REL;	eventP->timer.time.tv_sec=0;	eventP->timer.time.tv_usec=2500000/md_bpm;	eventP=(SamModEvent *)((char *)eventP+sizeof(SamModTimerEvent));	eventP->type=SAM_MOD_EVENT_ECHO;	eventP->echo.closure=(void *)(ticker_idx+1);	eventP=(SamModEvent *)((char *)eventP+sizeof(SamModEchoEvent));	if(wait_echo)		while(read(modfd, &event, sizeof(event))>0 && (long)event.echo.closure!=ticker_idx);	wait_echo=1;	ticker_idx++;	(*md_player)();	write(modfd, eventBuf, (char *)eventP-(char *)eventBuf);}static void voiceSetVolume(UBYTE voice, UWORD vol){	if(voice>=SAM_NUM_VOICES)		return;	voices[voice].vol=vol<=255 ? vol : 255;	voices[voice].pending|=PENDING_VOLUME;}static UWORD voiceGetVolume(UBYTE voice){	return voice<SAM_NUM_VOICES ? voices[voice].vol : 0;}static void voiceSetFrequency(UBYTE voice, ULONG freq){	if(voice>=SAM_NUM_VOICES)		return;	voices[voice].freq=freq;	voices[voice].pending|=PENDING_FREQ;}static ULONG voiceGetFrequency(UBYTE voice){	return voice<SAM_NUM_VOICES ? voices[voice].freq : 0;}static void voiceSetPanning(UBYTE voice, ULONG pan){	if(voice>=SAM_NUM_VOICES)		return;	voices[voice].pan=pan<=255 ? pan : 255;	voices[voice].pending|=PENDING_VOLUME;}static ULONG voiceGetPanning(UBYTE voice){	return voice<SAM_NUM_VOICES ? voices[voice].pan : 0x80;}static void voicePlay(UBYTE voice, SWORD handle, ULONG start, ULONG length, ULONG loopstart, ULONG repend, UWORD flags){	Voice *voiceP;	if(voice>=SAM_NUM_VOICES)		return;	voiceP=voices+voice;	voiceP->handle=handle;	voiceP->flags=flags;	voiceP->start=start;	voiceP->length=length;	voiceP->loopstart=loopstart;	voiceP->repend=repend;	voiceP->flags=flags;	voiceP->pending&=~PENDING_STOP;	voiceP->pending|=PENDING_PLAY;}static void voiceStop(UBYTE voice){	if(voice>=SAM_NUM_VOICES)		return;	voices[voice].pending&=~PENDING_PLAY;	voices[voice].pending|=PENDING_STOP;}static BOOL voiceStopped(UBYTE voice){	if(voice>=SAM_NUM_VOICES)		return 1;	return voice<SAM_NUM_VOICES ? !voices[voice].playing : 1;}static SLONG voiceGetPosition(UBYTE voice){	return -1;}static ULONG voiceRealVolume(UBYTE voice){	return 0;}MIKMODAPI MDRIVER drv_sam9407={	NULL,	"sam9407 driver",	"Linux sam9407 driver v1.0",	SAM_NUM_VOICES, 0,	"sam9407",	commandLine,	isPresent,	sampleLoad,	sampleUnload,	freeSampleSpace,	realSampleLength,	init,	exitHook,	reset,	setNumVoices,	playStart,	playStop,	update,	NULL,	voiceSetVolume,	voiceGetVolume,	voiceSetFrequency,	voiceGetFrequency,	voiceSetPanning,	voiceGetPanning,	voicePlay,	voiceStop,	voiceStopped,	voiceGetPosition,	voiceRealVolume};#elseMISSING(drv_sam9407);#endif/* ex:set ts=4: */

⌨️ 快捷键说明

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