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

📄 sun_a.c

📁 MIDI解码程序(用VC编写)
💻 C
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    sun_a.c - Functions to play sound on a Sun and NetBSD /dev/audio. 				Written by Masanao Izumo <mo@goice.co.jp>*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#ifndef NO_STRING_H#include <string.h>#endif#include <fcntl.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/filio.h>#include <sys/stat.h>#include <signal.h>#include <unistd.h>#ifdef HAVE_STROPTS_H#include <stropts.h>#endif /* HAVE_STROPTS_H */#if defined(HAVE_SYS_AUDIOIO_H)#include <sys/audioio.h>#elif defined(HAVE_SUN_AUDIOIO_H)#include <sun/audioio.h>#endif#include "timidity.h"#include "common.h"#include "aenc.h"#include "output.h"#include "controls.h"#if defined(__NetBSD__) /* NetBSD */#ifdef LITTLE_ENDIAN#define AUDIO_LINEAR_TAG	AUDIO_ENCODING_SLINEAR_LE#else#define AUDIO_LINEAR_TAG	AUDIO_ENCODING_SLINEAR_BE#endif#else /* Sun */#define AUDIO_LINEAR_TAG	AUDIO_ENCODING_LINEAR#endif#ifdef LITTLE_ENDIAN#define SUNAUDIO_AENC_SIGWORD	AENC_SIGWORDL#else#define SUNAUDIO_AENC_SIGWORD	AENC_SIGWORDB#endif#define AUDIO_DEV    "/dev/audio"#define AUDIO_CTLDEV "/dev/audioctl"static int open_output(void); /* 0=success, 1=warning, -1=fatal error */static void close_output(void);static int output_data(char *buf, int32 bytes);static int acntl(int request, void *arg);static int output_counter, play_samples_offset;/* export the playback mode */#define dpm sun_play_modePlayMode dpm = {    DEFAULT_RATE, PE_16BIT|PE_SIGNED,    PF_PCM_STREAM|PF_CAN_TRACE,    -1,    {0,0,0,0,0}, /* no extra parameters so far */#if defined(sun)    "Sun audio device",#elif defined(__NetBSD__)    "NetBSD audio device",#else    AUDIO_DEV,#endif    'd',    AUDIO_DEV,    open_output,    close_output,    output_data,    acntl};static int audioctl_fd = -1;static int sun_audio_encoding(int enc){    if(enc & PE_ULAW)	return AUDIO_ENCODING_ULAW;    if(enc & PE_ALAW)	return AUDIO_ENCODING_ALAW;#ifdef AUDIO_ENCODING_LINEAR8    if(!(enc & PE_16BIT))	return AUDIO_ENCODING_LINEAR8;#else    if(!(enc & PE_16BIT))	return 105;#endif /* AUDIO_ENCODING_LINEAR8 */    return AUDIO_LINEAR_TAG;}static int sun_audio_getinfo(audio_info_t *auinfo){    AUDIO_INITINFO(auinfo);    return ioctl(audioctl_fd, AUDIO_GETINFO, auinfo);}static int sun_audio_setinfo(audio_info_t *auinfo){    return ioctl(dpm.fd, AUDIO_SETINFO, auinfo);}static int open_output(void){    int include_enc = 0, exclude_enc = PE_BYTESWAP;    struct stat sb;    audio_info_t auinfo;    char *audio_dev, *audio_ctl_dev, *tmp_audio;    /* See if the AUDIODEV environment variable is defined, and set the       audio device accordingly  - Lalit Chhabra 23/Oct/2001 */    if((audio_dev  = getenv("AUDIODEV")) != NULL)    {      dpm.id_name = safe_malloc(strlen(audio_dev)+1);      dpm.name = safe_malloc(strlen(audio_dev)+1);      strcpy(dpm.name, audio_dev);      strcpy(dpm.id_name, audio_dev);      tmp_audio = safe_malloc(strlen(audio_dev) + 3);      audio_ctl_dev = safe_malloc(strlen(audio_dev) + 3);      strcpy(tmp_audio, audio_dev);      strcpy(audio_ctl_dev, strcat(tmp_audio, "ctl"));    }    else    {      audio_ctl_dev = safe_malloc(strlen(AUDIO_CTLDEV) + 3);      strcpy(audio_ctl_dev, AUDIO_CTLDEV);    }    output_counter = play_samples_offset = 0;    /* Open the audio device */    if((audioctl_fd = open(audio_ctl_dev, O_RDWR)) < 0)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		  "%s: %s", audio_ctl_dev, strerror(errno));	return -1;    }/* ############## */#if 0    if((dpm.fd = open(dpm.name, O_WRONLY | O_NDELAY)) == -1)    {	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,		  "%s: %s", dpm.name, strerror(errno));	if(errno == EBUSY)	{	    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)	    {		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,			  "%s: %s", dpm.name, strerror(errno));		close_output();		return -1;	    }	}    }#endif    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		  "%s: %s", dpm.name, strerror(errno));	close_output();	return -1;    }    if(stat(dpm.name, &sb) < 0)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		  "%s: %s", dpm.name, strerror(errno));	close_output();	return -1;    }    if(!S_ISCHR(sb.st_mode))    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		  "%s: Not a audio device", dpm.name);	close_output();	return -1;    }    if(sun_audio_getinfo(&auinfo) < 0)    { 	/* from Francesco Zanichelli's */	/* If it doesn't give info, it probably won't take requests	    either. Assume it's an old device that does 8kHz uLaw only.	      Disclaimer: I don't know squat about the various Sun audio		  devices, so if this is not what we should do, I'll gladly		      accept modifications. */	ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Cannot inquire %s", dpm.name);	include_enc = PE_ULAW|PE_ALAW|PE_MONO;	exclude_enc = PE_SIGNED|PE_16BIT|PE_BYTESWAP;	dpm.encoding = validate_encoding(dpm.encoding,					 include_enc, exclude_enc);	if(dpm.rate != 8000)	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		      "Sample rate is changed %d to 8000",		      dpm.rate);	dpm.rate = 8000;	return 1;    }    if(!(dpm.encoding & PE_16BIT))	exclude_enc |= PE_SIGNED; /* Always unsigned */    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);    AUDIO_INITINFO(&auinfo);    auinfo.play.sample_rate = dpm.rate;    auinfo.play.channels = (dpm.encoding & PE_MONO) ? 1 : 2;    auinfo.play.encoding = sun_audio_encoding(dpm.encoding);    auinfo.play.precision = (dpm.encoding & PE_16BIT) ? 16 : 8;    if(sun_audio_setinfo(&auinfo) == -1)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		  "rate=%d, channels=%d, precision=%d, encoding=%s",		  auinfo.play.sample_rate, auinfo.play.channels,		  auinfo.play.precision, output_encoding_string(dpm.encoding));	close_output();	return -1;    }    return 0;}static void close_output(void){    if(dpm.fd != -1)    {	close(dpm.fd);	dpm.fd = -1;    }    if(audioctl_fd != -1)    {	close(audioctl_fd);	audioctl_fd = -1;    }}int output_data(char *buff, int32 nbytes){    int n;  retry_write:    n = write(dpm.fd, buff, nbytes);    if(n < 0)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",		  dpm.name, strerror(errno));	if(errno == EINTR || errno == EAGAIN)	    goto retry_write;	return -1;    }    output_counter += n;    return n;}#if !defined(I_FLUSH) || !defined(FLUSHW)static void null_proc(){}static int sun_discard_playing(void){    void (* orig_alarm_handler)();    orig_alarm_handler = signal(SIGALRM, null_proc);    ualarm(10000, 10000);    close_output();    ualarm(0, 0);    signal(SIGALRM, orig_alarm_handler);    return open_output();}#elsestatic int sun_discard_playing(void){    if(ioctl(dpm.fd, I_FLUSH, FLUSHW) < 0)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: (ioctl) %s",		  dpm.name, strerror(errno));	return -1;    }    return 0;}#endifstatic int acntl(int request, void *arg){    audio_info_t auinfo;    int i;    switch(request)    {      case PM_REQ_GETFILLED:	if(ioctl(audioctl_fd, AUDIO_GETINFO, &auinfo) < 0)	    return -1;#ifdef __NetBSD__	*((int *)arg) = auinfo.play.seek;#else	if(auinfo.play.samples == play_samples_offset)	    return -1; /* auinfo.play.samples is not active */	i = output_counter;	if(!(dpm.encoding & PE_MONO)) i >>= 1;	if(dpm.encoding & PE_16BIT) i >>= 1;	*((int *)arg) = i - (auinfo.play.samples - play_samples_offset);#endif	return 0;      case PM_REQ_GETSAMPLES:	if(ioctl(audioctl_fd, AUDIO_GETINFO, &auinfo) < 0)	    return -1;	if(auinfo.play.samples == play_samples_offset)	    return -1; /* auinfo.play.samples is not active */	*((int *)arg) = auinfo.play.samples - play_samples_offset;	return 0;      case PM_REQ_DISCARD:	if(ioctl(audioctl_fd, AUDIO_GETINFO, &auinfo) != -1)	    play_samples_offset = auinfo.play.samples;	output_counter = 0;	return sun_discard_playing();      case PM_REQ_FLUSH:	if(ioctl(audioctl_fd, AUDIO_GETINFO, &auinfo) != -1)	    play_samples_offset = auinfo.play.samples;	output_counter = 0;	return 0;      case PM_REQ_RATE: {	  audio_info_t auinfo;	  int rate;	  rate = *(int *)arg;	  AUDIO_INITINFO(&auinfo);	  auinfo.play.sample_rate = rate;	  if(sun_audio_setinfo(&auinfo) == -1)	      return -1;	  play_mode->rate = rate;	  return 0;        }    }    return -1;}

⌨️ 快捷键说明

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