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

📄 xskin_c.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    xskin interface by Daisuke nagano <breeze_geo@geocities.co.jp>*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <math.h>#include <sys/time.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#include "timidity.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "output.h"#include "controls.h"#include "miditrace.h"#include "xskin.h"#define MSGWINDOWstatic void ctl_total_time(int tt);static void ctl_master_volume(int mv);static void ctl_current_time(int secs, int v);static void ctl_lyric(int lyricid);static int ctl_open(int using_stdin, int using_stdout);static void ctl_close(void);static int ctl_read(int32 *valp);static int cmsg(int type, int verbosity_level, char *fmt, ...);static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]);static void ctl_event(CtlEvent *e);static void ctl_speana_data(double *val, int size);static void initialize_exp_hz_table( void );static void xskin_pipe_open(void);void xskin_pipe_write(char *);static int xskin_pipe_ready(void);int xskin_pipe_read(char *,int);static int isspeanaenabled;static unsigned char *speana_buf;static double exp_hz_table[SPE_W+1];static int xskin_ready = 0;#define FFTSIZE 1024 /* same as "soudspec.c" */#define NCOLOR  64   /* same as "soudspec.c" */#define DEFAULT_ZOOM (44100.0/1024.0*4.0) /* tekito---- */#define CTL_LAST_STATUS -1/**********************************************//* export the interface functions */#define ctl xskin_control_modeControlMode ctl={    "skin interface", 'i',    1,0,0,    0,    ctl_open,    ctl_close,    ctl_pass_playing_list,    ctl_read,    cmsg,    ctl_event};static char local_buf[300];static int pipe_in_fd,pipe_out_fd=-1;/***********************************************************************//* Put controls on the pipe                                            *//***********************************************************************/static int cmsg(int type, int verbosity_level, char *fmt, ...) {  va_list ap;  if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&      ctl.verbosity<verbosity_level)    return 0;  va_start(ap, fmt);#ifdef MSGWINDOW  if(!xskin_ready)#endif  {    vfprintf(stderr, fmt, ap);    fprintf(stderr, NLS);    va_end(ap);    return 0;  }  vsnprintf(local_buf+2,100,fmt,ap);  if(pipe_out_fd==-1) {      fputs(local_buf + 2, stderr);      fputs(NLS, stderr);  } else {    local_buf[0]='L';    local_buf[1]=' ';    xskin_pipe_write(local_buf);  }  va_end(ap);  return 0;}/*ARGSUSED*/static void ctl_total_time(int tt) {  static int previous_total_time=-1;  int sec,min;  sec=tt/play_mode->rate;  min = sec/60;  sec-= min*60;  if ( tt!=previous_total_time ) {    previous_total_time=tt;    sprintf(local_buf,"A %d",min*60+sec);    xskin_pipe_write(local_buf);  }  return;}/*ARGSUSED*/static void ctl_master_volume(int mv) {  static int lastvol = CTL_LAST_STATUS;  if ( mv != lastvol ) {    if ( mv == CTL_LAST_STATUS ) mv = lastvol;    else lastvol = mv;        sprintf( local_buf, "V %d", mv );    xskin_pipe_write(local_buf);  }  return;}static void ctl_current_time(int sec, int v) {  static int previous_sec=-1;  if (sec!=previous_sec) {    previous_sec=sec;    sprintf(local_buf,"T %02d:%02d",sec/60,sec%60);    xskin_pipe_write(local_buf);  }}static void ctl_lyric(int lyricid){    char *lyric;	static int lyric_col = 2;	static char lyric_buf[300];    lyric = event2string(lyricid);    if(lyric != NULL)    {	if(lyric[0] == ME_KARAOKE_LYRIC)	{	    if(lyric[1] == '/' || lyric[1] == '\\')	    {		lyric_buf[0] = 'L';		lyric_buf[1] = ' ';		snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "%s", lyric + 2);		xskin_pipe_write(lyric_buf);		lyric_col = strlen(lyric + 2) + 2;	    }	    else if(lyric[1] == '@')	    {		lyric_buf[0] = 'L';		lyric_buf[1] = ' ';		if(lyric[2] == 'L')		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "Language: %s", lyric + 3);		else if(lyric[2] == 'T')		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "Title: %s", lyric + 3);		else		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "%s", lyric + 1);		xskin_pipe_write(lyric_buf);	    }	    else	    {		lyric_buf[0] = 'L';		lyric_buf[1] = ' ';		snprintf(lyric_buf + lyric_col, sizeof (lyric_buf) - lyric_col, "%s", lyric + 1);		xskin_pipe_write(lyric_buf);		lyric_col += strlen(lyric + 1);	    }	}	else	{	    if(lyric[0] == ME_CHORUS_TEXT || lyric[0] == ME_INSERT_TEXT)		lyric_col = 0;	    snprintf(lyric_buf + lyric_col, sizeof (lyric_buf) - lyric_col, "%s", lyric + 1);	    xskin_pipe_write(lyric_buf);	}    }}static void ctl_speana_data(double *val, int size) {  /* 0 <= val[n] <= (AMP*NCOLOR) */  /* AMP and NCOLOR are defined in soundspec.c */  /* By default, AMP*NCOLOR = 1.0*64 */  /* size = FFTSIZE/2 = 512 */  /* FFTSIZE is also defined in soundspec.c */  /* val[n] is the value of FFTed audio data */#ifdef SUPPORT_SOUNDSPEC  int i;  int tx,x;  double px;  double s,a;  int n;  if ( isspeanaenabled ) {    px=0.0;    speana_buf[0] = (unsigned char)val[0];    for ( i=1 ; i<SPE_W-1 ; i++ ) {      s=0.0;      n=0;      tx=exp_hz_table[i];      x=(int)px;      do {	a=val[x];	s += a + (tx-x)*(val[x+1]-a);	n++;	x++;      } while ( x<tx );      s/=n;      s*=16;      if ( s<0 ) s=0;      if ( s>=NCOLOR ) s=NCOLOR-1;      speana_buf[i] = (unsigned char)(256*s/NCOLOR);      px=tx;    }    speana_buf[SPE_W-1] = val[FFTSIZE/2-1];    xskin_pipe_write( "W" );  }#endif /* SUPPORT_SOUNDSPEC */  return;}/*ARGSUSED*/static int ctl_open(int using_stdin, int using_stdout) {  ctl.opened=1;  initialize_exp_hz_table();  /* The child process won't come back from this call  */  xskin_pipe_open();  return 0;}static void ctl_close(void){  if (ctl.opened) {    xskin_pipe_write("Q");    ctl.opened=0;    pipe_out_fd=-1;    xskin_ready = 0;  }}static int exitflag=0,randomflag=0,repeatflag=0,selectflag=0;/*ARGSUSED*/static int ctl_blocking_read(int32 *valp  /* Now, valp is not used */ ) {  xskin_pipe_read(local_buf,sizeof(local_buf));  for (;;) {    switch (local_buf[0]) {    case 'P' : return RC_LOAD_FILE;    case 'U' : return RC_TOGGLE_PAUSE;    case 'S' : return RC_QUIT;    case 'N' : return RC_NEXT;    case 'B' : return RC_REALLY_PREVIOUS;    case 'R' : repeatflag=atoi(local_buf+2);return RC_NONE;    case 'D' : randomflag=atoi(local_buf+2);return RC_QUIT;    case 'L' : selectflag=atoi(local_buf+2);return RC_QUIT;    case 'V' : *valp     =atoi(local_buf+2);return RC_CHANGE_VOLUME;#ifdef SUPPORT_SOUNDSPEC    case 'W' : return RC_TOGGLE_CTL_SPEANA;#endif    case 'Q' :    default : exitflag=1;return RC_QUIT;    }  }}static int ctl_read(int32 *valp) {  if (xskin_pipe_ready()<=0) return RC_NONE;  return ctl_blocking_read(valp);}static void shuffle(int n,int *a) {  int i,j,tmp;  for (i=0;i<n;i++) {    j=int_rand(n);    tmp=a[i];    a[i]=a[j];    a[j]=tmp;  }}static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]) {  int current_no,command,i;  int32 val;  int *file_table;  char **titles;  char *p;  /* Wait prepare 'interface' */  xskin_pipe_read(local_buf,sizeof(local_buf));  if (strcmp("READY",local_buf)) return;  xskin_ready = 1;  /* receive shared memory buffer */  xskin_pipe_read(local_buf, sizeof(local_buf));  if (strcmp("ERROR",local_buf)) {    int shmid;    isspeanaenabled=1;    shmid = atoi(local_buf);    speana_buf = (unsigned char *)shmat(shmid,0,0);  } else {    isspeanaenabled=0;  }  /* Make title string */  titles=(char **)safe_malloc(number_of_files*sizeof(char *));  for (i=0;i<number_of_files;i++) {    p=strrchr(list_of_files[i],'/');    if (p==NULL) {      p=list_of_files[i];    } else p++;    sprintf(local_buf,"%d. %s",i+1,p);    titles[i]=(char *)safe_malloc(strlen(local_buf)+1);    strcpy(titles[i],local_buf);  }  /* Send title string */  sprintf(local_buf,"%d",number_of_files);  xskin_pipe_write(local_buf);  for (i=0;i<number_of_files;i++) xskin_pipe_write(titles[i]);  /* Make the table of play sequence */  file_table=(int *)safe_malloc(number_of_files*sizeof(int));  for (i=0;i<number_of_files;i++) file_table[i]=i;  /* Draw the title of the first file */  current_no=0;  sprintf(local_buf,"F %s",titles[file_table[0]]);  xskin_pipe_write(local_buf);  command=ctl_blocking_read(&val);  /* Main loop */  for (;;) {    /* Play file */    if (command==RC_LOAD_FILE) {      sprintf(local_buf,"F %s",titles[file_table[current_no]]);      xskin_pipe_write(local_buf);      command=play_midi_file(list_of_files[file_table[current_no]]);    } else {      /* Quit timidity*/      if (exitflag) return;      /* Stop playing */      if (command==RC_QUIT) {	sprintf(local_buf,"T 00:00");	xskin_pipe_write(local_buf);	/* Shuffle the table */	if (randomflag) {	  current_no=0;	  if (randomflag==1) {	    shuffle(number_of_files,file_table);	    randomflag=0;	    command=RC_LOAD_FILE;	    continue;	  }	  randomflag=0;	  for (i=0;i<number_of_files;i++) file_table[i]=i;	  sprintf(local_buf,"F %s",titles[file_table[current_no]]);	  xskin_pipe_write(local_buf);	}	/* Play the selected file */	if (selectflag) {	  for (i=0;i<number_of_files;i++)	    if (file_table[i]==selectflag-1) break;	  if (i!=number_of_files) current_no=i;	  selectflag=0;	  command=RC_LOAD_FILE;	  continue;	}      /* After the all file played */      } else if (command==RC_TUNE_END || command==RC_ERROR) {	if (current_no+1<number_of_files) {	  current_no++;	  command=RC_LOAD_FILE;	  continue;	/* Repeat */	} else if (repeatflag) {	  current_no=0;	  command=RC_LOAD_FILE;	  continue;	/* Off the play button */	} else {	  xskin_pipe_write("O");	}      /* Play the next */      } else if (command==RC_NEXT) {	if (current_no+1<number_of_files) current_no++;	command=RC_LOAD_FILE;	continue;      /* Play the previous */      } else if (command==RC_REALLY_PREVIOUS) {	if (current_no>0) current_no--;	command=RC_LOAD_FILE;	continue;      }      command=ctl_blocking_read(&val);    }  }}/* ------ Pipe handlers ----- */extern void xskin_start_interface(int);static void xskin_pipe_open(void) {  int cont_inter[2],inter_cont[2];  if (pipe(cont_inter)<0 || pipe(inter_cont)<0) exit(1);  if (fork()==0) {    close(cont_inter[1]);    close(inter_cont[0]);    pipe_in_fd=cont_inter[0];    pipe_out_fd=inter_cont[1];    xskin_start_interface(pipe_in_fd);  }  close(cont_inter[0]);  close(inter_cont[1]);  pipe_in_fd=inter_cont[0];  pipe_out_fd=cont_inter[1];}void xskin_pipe_write(char *buf) {  write(pipe_out_fd,buf,strlen(buf));  write(pipe_out_fd,"\n",1);}static int xskin_pipe_ready(void) {  fd_set fds;  static struct timeval tv;  int cnt;  FD_ZERO(&fds);  FD_SET(pipe_in_fd,&fds);  tv.tv_sec=0;  tv.tv_usec=0;  if((cnt=select(pipe_in_fd+1,&fds,NULL,NULL,&tv))<0)    return -1;  return cnt > 0 && FD_ISSET(pipe_in_fd, &fds) != 0;}int xskin_pipe_read(char *buf,int bufsize) {  int i;  bufsize--;  for (i=0;i<bufsize;i++) {    read(pipe_in_fd,buf+i,1);    if (buf[i]=='\n') break;  }  buf[i]=0;  return 0;}int xskin_pipe_read_direct(int32 *buf, int bufsize) {  read( pipe_in_fd, buf, bufsize );  return 0;}static void ctl_event(CtlEvent *e){    switch(e->type)    {    case CTLE_PLAY_START:      ctl_total_time((int)e->v1);      break;    case CTLE_CURRENT_TIME:      ctl_current_time((int)e->v1, (int)e->v2);      break;    case CTLE_MASTER_VOLUME:      ctl_master_volume((int)e->v1);      break;    case CTLE_LYRIC:      ctl_lyric((int)e->v1);      break;#ifdef SUPPORT_SOUNDSPEC    case CTLE_SPEANA:      ctl_speana_data((double *)e->v1, (int)e->v2);    break;#endif /* SUPPORT_SOUNDSPEC */    }}/* * interface_<id>_loader(); */ControlMode *interface_i_loader(void){    return &ctl;}static void initialize_exp_hz_table( void ) {  int i;  double r, x, w;    w = (double)play_mode->rate * 0.5 / DEFAULT_ZOOM;  r = exp(log(w) * (1.0/SPE_W));  w = (FFTSIZE/2.0) / (w - 1.0);  for(i = 0, x = 1.0; i <= SPE_W; i++, x *= r)    exp_hz_table[i] = (x - 1.0) * w;}

⌨️ 快捷键说明

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