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

📄 output.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    output.c    Audio output (to file / device) functions.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#ifdef STDC_HEADERS#include <string.h>#include <ctype.h>#elif HAVE_STRINGS_H#include <strings.h>#endif#include "timidity.h"#include "common.h"#include "output.h"#include "tables.h"#include "controls.h"#include "audio_cnv.h"int audio_buffer_bits = DEFAULT_AUDIO_BUFFER_BITS;/* These are very likely mutually exclusive.. */#if defined(AU_AUDRIV)extern PlayMode audriv_play_mode;#define DEV_PLAY_MODE &audriv_play_mode#elif defined(AU_SUN)extern PlayMode sun_play_mode;#define DEV_PLAY_MODE &sun_play_mode#elif defined(AU_OSS)extern PlayMode oss_play_mode;#define DEV_PLAY_MODE &oss_play_mode#elif defined(AU_HPUX_AUDIO)extern PlayMode hpux_play_mode;#define DEV_PLAY_MODE &hpux_play_mode#elif defined(AU_W32)extern PlayMode w32_play_mode;#define DEV_PLAY_MODE &w32_play_mode#elif defined(AU_BSDI)extern PlayMode bsdi_play_mode;#define DEV_PLAY_MODE &bsdi_play_mode#elif defined(__MACOS__)extern PlayMode mac_play_mode;#define DEV_PLAY_MODE &mac_play_mode#elif defined(AU_DARWIN)extern PlayMode darwin_play_mode;#define DEV_PLAY_MODE &darwin_play_mode#endif#ifdef AU_ALSAextern PlayMode alsa_play_mode;#endif /* AU_ALSA */#ifdef AU_HPUX_ALIBextern PlayMode hpux_nplay_mode;#endif /* AU_HPUX_ALIB */#ifdef AU_ARTSextern PlayMode arts_play_mode;#endif /* AU_ARTS */#ifdef AU_ESDextern PlayMode esd_play_mode;#endif /* AU_ESD */#ifdef AU_PORTAUDIO#ifndef AU_PORTAUDIO_DLLextern PlayMode portaudio_play_mode;#elseextern PlayMode portaudio_asio_play_mode;extern PlayMode portaudio_win_ds_play_mode;extern PlayMode portaudio_win_wmme_play_mode;#endif#endif /* AU_PORTAUDIO */#ifdef AU_JACKextern PlayMode jack_play_mode;#endif /* AU_NAS */#ifdef AU_NASextern PlayMode nas_play_mode;#endif /* AU_NAS */#ifdef AU_AOextern PlayMode ao_play_mode;#endif /* AU_AO */#ifndef __MACOS__/* These are always compiled in. */extern PlayMode raw_play_mode, wave_play_mode, au_play_mode, aiff_play_mode;extern PlayMode list_play_mode;#ifdef AU_VORBISextern PlayMode vorbis_play_mode;#endif /* AU_VORBIS */#ifdef AU_FLACextern PlayMode flac_play_mode;#endif /* AU_FLAC */#ifdef AU_SPEEXextern PlayMode speex_play_mode;#endif /* AU_SPEEX */#ifdef AU_GOGOextern PlayMode gogo_play_mode;#endif /* AU_GOGO */#endif /* !__MACOS__ */extern PlayMode modmidi_play_mode;PlayMode *play_mode_list[] = {#ifdef DEV_PLAY_MODE  DEV_PLAY_MODE,#endif#ifdef AU_ALSA  &alsa_play_mode,#endif /* AU_ALSA */#ifdef AU_HPUX_ALIB  &hpux_nplay_mode,#endif /* AU_HPUX_ALIB */#if defined(AU_ARTS)  &arts_play_mode,#endif /* AU_ARTS */#if defined(AU_ESD)  &esd_play_mode,#endif /* AU_ESD */#if defined(AU_PORTAUDIO)#ifndef AU_PORTAUDIO_DLL  &portaudio_play_mode,#else  &portaudio_asio_play_mode,  &portaudio_win_ds_play_mode,  &portaudio_win_wmme_play_mode,#endif#endif /* AU_PORTAUDIO */#if defined(AU_JACK)  &jack_play_mode,#endif /* AU_PORTAUDIO */#if defined(AU_NAS)  &nas_play_mode,#endif /* AU_NAS */#if defined(AU_AO)  &ao_play_mode,#endif /* AU_PORTAUDIO */#ifndef __MACOS__  &wave_play_mode,  &raw_play_mode,  &au_play_mode,  &aiff_play_mode,#ifdef AU_VORBIS  &vorbis_play_mode,#endif /* AU_VORBIS */#ifdef AU_FLAC  &flac_play_mode,#endif /* AU_FLAC */#ifdef AU_SPEEX  &speex_play_mode,#endif /* AU_SPEEX */#ifdef AU_GOGO  &gogo_play_mode,#endif /* AU_GOGO */  &list_play_mode,#endif /* __MACOS__ */  &modmidi_play_mode,  0};PlayMode *play_mode = NULL;PlayMode *target_play_mode = NULL;/*****************************************************************//* Some functions to convert signed 32-bit data to other formats */void s32tos8(int32 *lp, int32 c){    int8 *cp=(int8 *)(lp);    int32 l, i;    for(i = 0; i < c; i++)    {	l=(lp[i])>>(32-8-GUARD_BITS);	if (l>127) l=127;	else if (l<-128) l=-128;	cp[i] = (int8)(l);    }}void s32tou8(int32 *lp, int32 c){    uint8 *cp=(uint8 *)(lp);    int32 l, i;    for(i = 0; i < c; i++)    {	l=(lp[i])>>(32-8-GUARD_BITS);	if (l>127) l=127;	else if (l<-128) l=-128;	cp[i] = 0x80 ^ ((uint8) l);    }}void s32tos16(int32 *lp, int32 c){  int16 *sp=(int16 *)(lp);  int32 l, i;  for(i = 0; i < c; i++)    {      l=(lp[i])>>(32-16-GUARD_BITS);      if (l > 32767) l=32767;      else if (l<-32768) l=-32768;      sp[i] = (int16)(l);    }}void s32tou16(int32 *lp, int32 c){  uint16 *sp=(uint16 *)(lp);  int32 l, i;  for(i = 0; i < c; i++)    {      l=(lp[i])>>(32-16-GUARD_BITS);      if (l > 32767) l=32767;      else if (l<-32768) l=-32768;      sp[i] = 0x8000 ^ (uint16)(l);    }}void s32tos16x(int32 *lp, int32 c){  int16 *sp=(int16 *)(lp);  int32 l, i;  for(i = 0; i < c; i++)    {      l=(lp[i])>>(32-16-GUARD_BITS);      if (l > 32767) l=32767;      else if (l<-32768) l=-32768;      sp[i] = XCHG_SHORT((int16)(l));    }}void s32tou16x(int32 *lp, int32 c){  uint16 *sp=(uint16 *)(lp);  int32 l, i;  for(i = 0; i < c; i++)    {      l=(lp[i])>>(32-16-GUARD_BITS);      if (l > 32767) l=32767;      else if (l<-32768) l=-32768;      sp[i] = XCHG_SHORT(0x8000 ^ (uint16)(l));    }}#define MAX_24BIT_SIGNED (8388607)#define MIN_24BIT_SIGNED (-8388608)#define STORE_S24_LE(cp, l) *cp++ = l & 0xFF, *cp++ = l >> 8 & 0xFF, *cp++ = l >> 16#define STORE_S24_BE(cp, l) *cp++ = l >> 16, *cp++ = l >> 8 & 0xFF, *cp++ = l & 0xFF#define STORE_U24_LE(cp, l) *cp++ = l & 0xFF, *cp++ = l >> 8 & 0xFF, *cp++ = l >> 16 ^ 0x80#define STORE_U24_BE(cp, l) *cp++ = l >> 16 ^ 0x80, *cp++ = l >> 8 & 0xFF, *cp++ = l & 0xFF#ifdef LITTLE_ENDIAN  #define STORE_S24  STORE_S24_LE  #define STORE_S24X STORE_S24_BE  #define STORE_U24  STORE_U24_LE  #define STORE_U24X STORE_U24_BE#else  #define STORE_S24  STORE_S24_BE  #define STORE_S24X STORE_S24_LE  #define STORE_U24  STORE_U24_BE  #define STORE_U24X STORE_U24_LE#endifvoid s32tos24(int32 *lp, int32 c){	uint8 *cp = (uint8 *)(lp);	int32 l, i;	for(i = 0; i < c; i++)	{		l = (lp[i]) >> (32 - 24 - GUARD_BITS);		l = (l > MAX_24BIT_SIGNED) ? MAX_24BIT_SIGNED				: (l < MIN_24BIT_SIGNED) ? MIN_24BIT_SIGNED : l;		STORE_S24(cp, l);	}}void s32tou24(int32 *lp, int32 c){	uint8 *cp = (uint8 *)(lp);	int32 l, i;	for(i = 0; i < c; i++)	{		l = (lp[i]) >> (32 - 24 - GUARD_BITS);		l = (l > MAX_24BIT_SIGNED) ? MAX_24BIT_SIGNED				: (l < MIN_24BIT_SIGNED) ? MIN_24BIT_SIGNED : l;		STORE_U24(cp, l);	}}void s32tos24x(int32 *lp, int32 c){	uint8 *cp = (uint8 *)(lp);	int32 l, i;	for(i = 0; i < c; i++)	{		l = (lp[i]) >> (32 - 24 - GUARD_BITS);		l = (l > MAX_24BIT_SIGNED) ? MAX_24BIT_SIGNED				: (l < MIN_24BIT_SIGNED) ? MIN_24BIT_SIGNED : l;		STORE_S24X(cp, l);	}}void s32tou24x(int32 *lp, int32 c){	uint8 *cp = (uint8 *)(lp);	int32 l, i;	for(i = 0; i < c; i++)	{		l = (lp[i]) >> (32 - 24 - GUARD_BITS);		l = (l > MAX_24BIT_SIGNED) ? MAX_24BIT_SIGNED				: (l < MIN_24BIT_SIGNED) ? MIN_24BIT_SIGNED : l;		STORE_U24X(cp, l);	}}void s32toulaw(int32 *lp, int32 c){    int8 *up=(int8 *)(lp);    int32 l, i;    for(i = 0; i < c; i++)    {	l=(lp[i])>>(32-16-GUARD_BITS);	if (l > 32767) l=32767;	else if (l<-32768) l=-32768;	up[i] = AUDIO_S2U(l);    }}void s32toalaw(int32 *lp, int32 c){    int8 *up=(int8 *)(lp);    int32 l, i;    for(i = 0; i < c; i++)    {	l=(lp[i])>>(32-16-GUARD_BITS);	if (l > 32767) l=32767;	else if (l<-32768) l=-32768;	up[i] = AUDIO_S2A(l);    }}/* return: number of bytes */int32 general_output_convert(int32 *buf, int32 count){    int32 bytes;    if(!(play_mode->encoding & PE_MONO))	count *= 2; /* Stereo samples */    bytes = count;    if(play_mode->encoding & PE_16BIT)    {	bytes *= 2;	if(play_mode->encoding & PE_BYTESWAP)	{	    if(play_mode->encoding & PE_SIGNED)		s32tos16x(buf, count);	    else		s32tou16x(buf, count);	}	else if(play_mode->encoding & PE_SIGNED)	    s32tos16(buf, count);	else	    s32tou16(buf, count);    }	else if(play_mode->encoding & PE_24BIT) {		bytes *= 3;		if(play_mode->encoding & PE_BYTESWAP)		{			if(play_mode->encoding & PE_SIGNED)			s32tos24x(buf, count);			else			s32tou24x(buf, count);		} else if(play_mode->encoding & PE_SIGNED)			s32tos24(buf, count);		else			s32tou24(buf, count);    }	else if(play_mode->encoding & PE_ULAW)	s32toulaw(buf, count);    else if(play_mode->encoding & PE_ALAW)	s32toalaw(buf, count);    else if(play_mode->encoding & PE_SIGNED)	s32tos8(buf, count);    else	s32tou8(buf, count);    return bytes;}int validate_encoding(int enc, int include_enc, int exclude_enc){    const char *orig_enc_name, *enc_name;    int orig_enc;    orig_enc = enc;    orig_enc_name = output_encoding_string(enc);    enc |= include_enc;    enc &= ~exclude_enc;    if(enc & (PE_ULAW|PE_ALAW))	enc &= ~(PE_24BIT|PE_16BIT|PE_SIGNED|PE_BYTESWAP);    if(!(enc & PE_16BIT || enc & PE_24BIT))	enc &= ~PE_BYTESWAP;	if(enc & PE_24BIT)	enc &= ~PE_16BIT;	/* 24bit overrides 16bit */    enc_name = output_encoding_string(enc);    if(strcmp(orig_enc_name, enc_name) != 0)	ctl->cmsg(CMSG_WARNING, VERB_NOISY,		  "Notice: Audio encoding is changed `%s' to `%s'",		  orig_enc_name, enc_name);    return enc;}const char *output_encoding_string(int enc){    if(enc & PE_MONO)    {	if(enc & PE_16BIT)	{	    if(enc & PE_SIGNED)		return "16bit (mono)";	    else		return "unsigned 16bit (mono)";	}	else if(enc & PE_24BIT)	{	    if(enc & PE_SIGNED)		return "24bit (mono)";	    else		return "unsigned 24bit (mono)";	}	else	{	    if(enc & PE_ULAW)		return "U-law (mono)";	    else if(enc & PE_ALAW)		return "A-law (mono)";	    else if(enc & PE_SIGNED)		return "8bit (mono)";	    else		return "unsigned 8bit (mono)";	}    }    else if(enc & PE_16BIT)    {	if(enc & PE_BYTESWAP)	{	    if(enc & PE_SIGNED)		return "16bit (swap)";	    else		return "unsigned 16bit (swap)";	}	else if(enc & PE_SIGNED)	    return "16bit";	else	    return "unsigned 16bit";    }    else if(enc & PE_24BIT)    {	if(enc & PE_SIGNED)	    return "24bit";	else	    return "unsigned 24bit";    }    else	if(enc & PE_ULAW)	    return "U-law";	else if(enc & PE_ALAW)	    return "A-law";	else if(enc & PE_SIGNED)	    return "8bit";	else	    return "unsigned 8bit";    /*NOTREACHED*/}/* mode  0,1: Default mode.  2: Remove the directory path of input_filename, then add output_dir.  3: Replace directory separator characters ('/','\',':') with '_', then add output_dir. */char *create_auto_output_name(const char *input_filename, char *ext_str, char *output_dir, int mode){  char *output_filename;  char *ext, *p;  int32 dir_len = 0;  char ext_str_tmp[65];  output_filename = (char *)safe_malloc((output_dir?strlen(output_dir):0) + strlen(input_filename) + 6);  if(output_filename==NULL)    return NULL;  output_filename[0] = '\0';  if(output_dir!=NULL && (mode==2 || mode==3)) {    strcat(output_filename,output_dir);    dir_len = strlen(output_filename);#ifndef __W32__    if(dir_len>0 && output_filename[dir_len-1]!=PATH_SEP){#else      if(dir_len>0 && output_filename[dir_len-1]!='/' && output_filename[dir_len-1]!='\\' && output_filename[dir_len-1]!=':'){#endif	strcat(output_filename,PATH_STRING);	dir_len++;      }    }    strcat(output_filename, input_filename);    if((ext = strrchr(output_filename, '.')) == NULL)      ext = output_filename + strlen(output_filename);    else {      /* strip ".gz" */      if(strcasecmp(ext, ".gz") == 0) {	*ext = '\0';	if((ext = strrchr(output_filename, '.')) == NULL)	  ext = output_filename + strlen(output_filename);      }    }    /* replace '\' , '/' or PATH_SEP between '#' and ext */    p = strrchr(output_filename,'#');    if(p!=NULL){      char *p1;#ifdef _mbsrchr#define STRCHR(a,b) _mbschr(a,b)#else#define STRCHR(a,b) strchr(a,b)#endif#ifndef __W32__      p1 = p + 1;      while((p1 = STRCHR(p1,PATH_SEP))!=NULL && p1<ext){        *p1 = '_';	p1++;      }#else      p1 = p + 1;      while((p1 = STRCHR(p1,'\\'))!=NULL && p1<ext){      	*p1 = '_';	p1++;      }      p1 = p;      while((p1 = STRCHR(p1,'/'))!=NULL && p1<ext){	*p1 = '_';	p1++;      }#endif#undef STRCHR    }    /* replace '.' and '#' before ext */    for(p = output_filename; p < ext; p++)#ifndef __W32__      if(*p == '.' || *p == '#')#else	if(*p == '#')#endif	  *p = '_';    if(mode==2){      char *p1,*p2,*p3;#ifndef __W32__      p = strrchr(output_filename+dir_len,PATH_SEP);#else#ifdef _mbsrchr#define STRRCHR _mbsrchr#else#define STRRCHR strrchr#endif      p1 = STRRCHR(output_filename+dir_len,'/');      p2 = STRRCHR(output_filename+dir_len,'\\');      p3 = STRRCHR(output_filename+dir_len,':');#undef STRRCHR      p1>p2 ? (p1>p3 ? (p = p1) : (p = p3)) : (p2>p3 ? (p = p2) : (p = p3));#endif      if(p!=NULL){	for(p1=output_filename+dir_len,p2=p+1; *p2; p1++,p2++)	  *p1 = *p2;	*p1 = '\0';      }    }    if(mode==3){      for(p=output_filename+dir_len; *p; p++)#ifndef __W32__	if(*p==PATH_SEP)#else	  if(*p=='/' || *p=='\\' || *p==':')#endif	    *p = '_';    }    if((ext = strrchr(output_filename, '.')) == NULL)      ext = output_filename + strlen(output_filename);    if(*ext){      strncpy(ext_str_tmp,ext_str,64);      ext_str_tmp[64]=0;      if(isupper(*(ext + 1))){	for(p=ext_str_tmp;*p;p++)	  *p = toupper(*p);	*p = '\0';      } else {	for(p=ext_str_tmp;*p;p++)	  *p = tolower(*p);	*p = '\0';      }      strcpy(ext+1,ext_str_tmp);    }    return output_filename;}

⌨️ 快捷键说明

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