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

📄 drv_sun.c

📁 wince下著名的视频播放器源码
💻 C
字号:
/*	MikMod sound library	(c) 1998, 1999, 2000, 2001, 2002 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_sun.c,v 1.3 2004/02/10 14:02:24 raph Exp $  Driver for output on the Sun audio device (/dev/audio).  Also works under NetBSD and OpenBSD==============================================================================*//*	Written by Valtteri Vuorikoski <vuori@sci.fi>	NetBSD/OpenBSD code from Miodrag Vallat <miod@mikmod.org>*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "mikmod_internals.h"#ifdef DRV_SUN#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#include <sys/types.h>#ifdef HAVE_SUN_AUDIOIO_H#include <sun/audioio.h>#endif#ifdef HAVE_SYS_AUDIOIO_H#include <sys/audioio.h>#endif#ifdef SUNOSextern int ioctl(int, unsigned long, ...);extern int fputs(const char *, FILE *);#endif#define DEFAULT_FRAGSIZE 12#if !defined __NetBSD__  && !defined __OpenBSD__#ifdef HAVE_SUN_AUDIOIO_H#define SUNOS4#else#define SOLARIS#endif#endif/* Sound device to open */#ifdef SUNOS4#define SOUNDDEVICE "/dev/sound"#else /* Solaris, *BSD */#define SOUNDDEVICE "/dev/audio"#endif/* Solaris doesn't have these */#ifdef SOLARIS#define AUDIO_ENCODING_SLINEAR AUDIO_ENCODING_LINEAR#define AUDIO_ENCODING_ULINEAR AUDIO_ENCODING_LINEAR8#endif/* Compatibility defines, for old *BSD or SunOS systems */#ifndef AUDIO_ENCODING_PCM16#define AUDIO_ENCODING_PCM16 AUDIO_ENCODING_LINEAR#endif#ifndef AUDIO_ENCODING_PCM8#define AUDIO_ENCODING_PCM8 AUDIO_ENCODING_LINEAR8#endif#ifndef AUDIO_ENCODING_SLINEAR_LE#define AUDIO_ENCODING_SLINEAR_LE AUDIO_ENCODING_PCM16#endif#ifndef AUDIO_ENCODING_ULINEAR_LE#define AUDIO_ENCODING_ULINEAR_LE AUDIO_ENCODING_PCM8#endif#ifndef AUDIO_ENCODING_SLINEAR#if BYTE_ORDER == BIG_ENDIAN#define AUDIO_ENCODING_SLINEAR AUDIO_ENCODING_SLINEAR_BE#else#define AUDIO_ENCODING_SLINEAR AUDIO_ENCODING_SLINEAR_LE#endif#endif#ifndef AUDIO_ENCODING_ULINEAR#if BYTE_ORDER == BIG_ENDIAN#define AUDIO_ENCODING_ULINEAR AUDIO_ENCODING_ULINEAR_BE#else#define AUDIO_ENCODING_ULINEAR AUDIO_ENCODING_ULINEAR_LE#endif#endif/* Compatibility defines, for old *BSD systems */#ifndef AUDIO_SPEAKER#define AUDIO_SPEAKER 0x01#endif#ifndef AUDIO_HEADPHONE#define AUDIO_HEADPHONE 0x02#endif/* ``normalize'' AUDIO_ENCODING_xxx values for comparison */static int normalize(int encoding){	switch (encoding) {#ifdef AUDIO_ENCODING_LINEAR	case AUDIO_ENCODING_LINEAR:			return AUDIO_ENCODING_PCM16;#endif#ifdef AUDIO_ENCODING_LINEAR8	case AUDIO_ENCODING_LINEAR8:			return AUDIO_ENCODING_PCM8;#endif#if BYTE_ORDER == BIG_ENDIAN#ifdef AUDIO_ENCODING_SLINEAR_BE	case AUDIO_ENCODING_SLINEAR:		return AUDIO_ENCODING_SLINEAR_BE;#endif#ifdef AUDIO_ENCODING_ULINEAR_BE	case AUDIO_ENCODING_ULINEAR:		return AUDIO_ENCODING_ULINEAR_BE;#endif#else#ifdef AUDIO_ENCODING_SLINEAR_LE	case AUDIO_ENCODING_SLINEAR:		return AUDIO_ENCODING_SLINEAR_LE;#endif#ifdef AUDIO_ENCODING_ULINEAR_LE	case AUDIO_ENCODING_ULINEAR:		return AUDIO_ENCODING_ULINEAR_LE;#endif#endif	default:		return encoding;	}}static int sndfd = -1;static unsigned int port = 0;static int play_encoding;static int play_precision;static int fragsize = 1 << DEFAULT_FRAGSIZE;static SBYTE *audiobuffer = NULL;static void Sun_CommandLine(CHAR *cmdline){	CHAR *ptr;	if ((ptr = MD_GetAtom("buffer", cmdline, 0))) {		int buf = atoi(ptr);		if (buf >= 7 && buf <= 17)			fragsize = 1 << buf;		free(ptr);	}	if ((ptr = MD_GetAtom("headphone", cmdline, 1))) {		port = AUDIO_HEADPHONE;		free(ptr);	} else if ((ptr = MD_GetAtom("speaker", cmdline, 1))) {		port = AUDIO_SPEAKER;		free(ptr);	}}static BOOL Sun_IsThere(void){	if (getenv("AUDIODEV"))		return (access(getenv("AUDIODEV"), W_OK) == 0);	else {		if (access(SOUNDDEVICE, W_OK) == 0)			return 1;#if defined __NetBSD__ || defined __OpenBSD__		/* old OpenBSD/sparc installation program creates /dev/audio0 but no		   /dev/audio. Didn't check NetBSD behaviour */		if (access(SOUNDDEVICE "0", W_OK) == 0)			return 1;#endif	}	return 0;}static BOOL Sun_Init(void){	int play_stereo, play_rate;#ifdef SUNOS4	int audiotype;#else	audio_device_t audiotype;#endif	struct audio_info audioinfo;	if (getenv("AUDIODEV"))		sndfd = open(getenv("AUDIODEV"), O_WRONLY);	else {		sndfd = open(SOUNDDEVICE, O_WRONLY);#if defined __NetBSD__ || defined __OpenBSD__		if (sndfd < 0)			sndfd = open(SOUNDDEVICE "0", O_WRONLY);#endif	}	if (sndfd < 0) {		_mm_errno = MMERR_OPENING_AUDIO;		return 1;	}	if (!(audiobuffer = (SBYTE *)_mm_malloc(fragsize)))		return 1;	play_precision = (md_mode & DMODE_16BITS) ? 16 : 8;	play_stereo = (md_mode & DMODE_STEREO) ? 2 : 1;	play_rate = md_mixfreq;	/* attempt to guess the encoding */	play_encoding = -1;	if (ioctl(sndfd, AUDIO_GETDEV, &audiotype) < 0) {#ifdef MIKMOD_DEBUG		fputs("\rSun driver warning: could not determine audio device type\n",			  stderr);#endif	} else {#if defined SUNOS4				/* SunOS 4 */		switch (audiotype) {		  case AUDIO_DEV_AMD:			/* AMD 79C30 */			/* 8bit mono ulaw 8kHz */		  	play_rate = md_mixfreq = 8000;			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);			play_precision = 8;			play_stereo = 1;			play_encoding = AUDIO_ENCODING_ULAW;			break;		  case AUDIO_DEV_SPEAKERBOX:		  case AUDIO_DEV_CODEC:			/* CS 4231 or DBRI or speaker box */			/* 16bit mono/stereo linear 8kHz - 48kHz */			if (play_precision == 16)				play_encoding = AUDIO_ENCODING_LINEAR;			/* 8bit mono ulaw 8kHz - 48kHz */			else if (play_precision == 8) {				md_mode &= ~(DMODE_STEREO);				play_stereo = 1;				play_encoding = AUDIO_ENCODING_ULAW;			} else {				_mm_errno = MMERR_SUN_INIT;				return 1;			}			break;		}#elif defined SOLARIS			/* Solaris */		if (!strcmp(audiotype.name, "SUNW,am79c30")) {			/* AMD 79C30 */			/* 8bit mono ulaw 8kHz */		  	play_rate = md_mixfreq = 8000;			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);			play_precision = 8;			play_stereo = 1;			play_encoding = AUDIO_ENCODING_ULAW;		} else			if ((!strcmp(audiotype.name, "SUNW,CS4231")) ||				(!strcmp(audiotype.name, "SUNW,dbri")) ||				(!strcmp(audiotype.name, "speakerbox"))) {			/* CS 4231 or DBRI or speaker box */			/* 16bit mono/stereo linear 8kHz - 48kHz */			if (play_precision == 16)				play_encoding = AUDIO_ENCODING_LINEAR;			/* 8bit mono ulaw 8kHz - 48kHz */			else if (play_precision == 8) {				md_mode &= ~(DMODE_STEREO);				play_stereo = 1;				play_encoding = AUDIO_ENCODING_ULAW;			} else {				_mm_errno = MMERR_SUN_INIT;				return 1;			}		}#else /* NetBSD, OpenBSD */		if (!strcmp(audiotype.name, "amd7930")) {			/* AMD 79C30 */			/* 8bit mono ulaw 8kHz */		  	play_rate = md_mixfreq = 8000;			md_mode &= ~(DMODE_STEREO | DMODE_16BITS);			play_precision = 8;			play_stereo = 1;			play_encoding = AUDIO_ENCODING_ULAW;		}		if ((!strcmp(audiotype.name, "Am78C201")) ||			(!strcmp(audiotype.name, "UltraSound")) 		   ) {			/* Gravis UltraSound, AMD Interwave and compatible cards */			/* 16bit stereo linear 44kHz */		  	play_rate = md_mixfreq = 44100;			md_mode |= (DMODE_STEREO | DMODE_16BITS);			play_precision = 16;			play_stereo = 2;			play_encoding = AUDIO_ENCODING_SLINEAR;		}#endif	}	/* Sound devices which were not handled above don't have specific	   limitations, so try and guess optimal settings */	if (play_encoding == -1) {		if ((play_precision == 8) && (play_stereo == 1) &&			(play_rate <= 8000)) play_encoding = AUDIO_ENCODING_ULAW;		else#ifdef SUNOS4			play_encoding = AUDIO_ENCODING_LINEAR;#else			play_encoding =				(play_precision ==				 16) ? AUDIO_ENCODING_SLINEAR : AUDIO_ENCODING_ULINEAR;#endif	}	/* get current audio settings if we want to keep the playback output	   port */	if (!port) {		AUDIO_INITINFO(&audioinfo);		if (ioctl(sndfd, AUDIO_GETINFO, &audioinfo) < 0) {			_mm_errno = MMERR_SUN_INIT;			return 1;		}		port = audioinfo.play.port;	}	AUDIO_INITINFO(&audioinfo);	audioinfo.play.precision = play_precision;	audioinfo.play.channels = play_stereo;	audioinfo.play.sample_rate = play_rate;	audioinfo.play.encoding = play_encoding;	audioinfo.play.port = port;#if defined __NetBSD__ || defined __OpenBSD__#if defined AUMODE_PLAY_ALL	audioinfo.mode = AUMODE_PLAY | AUMODE_PLAY_ALL;#else	audioinfo.mode = AUMODE_PLAY;#endif#endif	if (ioctl(sndfd, AUDIO_SETINFO, &audioinfo) < 0) {		_mm_errno = MMERR_SUN_INIT;		return 1;	}	/* check if our changes were accepted */	if (ioctl(sndfd, AUDIO_GETINFO, &audioinfo) < 0) {		_mm_errno = MMERR_SUN_INIT;		return 1;	}	if ((audioinfo.play.precision != play_precision) ||		(audioinfo.play.channels != play_stereo) ||		(normalize(audioinfo.play.encoding) != normalize(play_encoding))) {		_mm_errno = MMERR_SUN_INIT;		return 1;	}	if (audioinfo.play.sample_rate != play_rate) {		/* Accept a shift inferior to 5% of the expected rate */		int delta = audioinfo.play.sample_rate - play_rate;		if (delta < 0)			delta = -delta;		if (delta * 20 > play_rate) {			_mm_errno = MMERR_SUN_INIT;			return 1;		}		/* Align to what the card gave us */		md_mixfreq = audioinfo.play.sample_rate;	}	return VC_Init();}static void Sun_Exit(void){	VC_Exit();	_mm_free(audiobuffer);	if (sndfd >= 0) {		close(sndfd);		sndfd = -1;	}}static void Sun_Update(void){	int done;	done = VC_WriteBytes((char *)audiobuffer, fragsize);	if (play_encoding == AUDIO_ENCODING_ULAW)		unsignedtoulaw(audiobuffer, done);	write(sndfd, audiobuffer, done);}static void Sun_Pause(void){	int done;	done = VC_SilenceBytes((char *)audiobuffer, fragsize);	write(sndfd, audiobuffer, done);}static BOOL Sun_PlayStart(void){	struct audio_info audioinfo;	AUDIO_INITINFO(&audioinfo);	audioinfo.play.pause = 0;	if (ioctl(sndfd, AUDIO_SETINFO, &audioinfo) < 0)		return 1;	return VC_PlayStart();}static void Sun_PlayStop(void){	struct audio_info audioinfo;	VC_PlayStop();	if (ioctl(sndfd, AUDIO_DRAIN) < 0)		return;	AUDIO_INITINFO(&audioinfo);	audioinfo.play.pause = 1;	ioctl(sndfd, AUDIO_SETINFO, &audioinfo);}MIKMODAPI MDRIVER drv_sun = {	NULL,#if defined __OpenBSD__	"OpenBSD Audio",	"OpenBSD audio driver v1.0",#elif defined __NetBSD__	"NetBSD Audio",	"NetBSD audio driver v1.0",#elif defined SUNOS4	"SunOS Audio",	"SunOS audio driver v1.4",#elif defined SOLARIS	"Solaris Audio",	"Solaris audio driver v1.4",#endif	0, 255,	"audio",        "buffer:r:7,17,12:Audio buffer log2 size\n"#if defined(SUNOS) || defined(SOLARIS)        "headphone:b:0:Use headphone\n"        "speaker:b:0:Use speaker\n"#endif	,	Sun_CommandLine,	Sun_IsThere,	VC_SampleLoad,	VC_SampleUnload,	VC_SampleSpace,	VC_SampleLength,	Sun_Init,	Sun_Exit,	NULL,	VC_SetNumVoices,	Sun_PlayStart,	Sun_PlayStop,	Sun_Update,	Sun_Pause,	VC_VoiceSetVolume,	VC_VoiceGetVolume,	VC_VoiceSetFrequency,	VC_VoiceGetFrequency,	VC_VoiceSetPanning,	VC_VoiceGetPanning,	VC_VoicePlay,	VC_VoiceStop,	VC_VoiceStopped,	VC_VoiceGetPosition,	VC_VoiceRealVolume};#elseMISSING(drv_sun);#endif/* ex:set ts=4: */

⌨️ 快捷键说明

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