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

📄 server_c.c

📁 linux上播放midi音乐,但是要一些设置.可网上查找. 软件名称: TiMidity++-2.13.0.tar
💻 C
📖 第 1 页 / 共 3 页
字号:
	* (65536.0/500000.0) / (double)curr_timebase,    sample_correction = (int32)(a) & 0xFFFF;    sample_increment = (int32)(a) >> 16;}static void add_tick(int tick){    int32 samples_to_do;    MidiEvent ev;    samples_to_do = sample_increment * tick;    sample_cum += sample_correction * tick;    if(sample_cum & 0xFFFF0000)    {	samples_to_do += ((sample_cum >> 16) & 0xFFFF);	sample_cum &= 0x0000FFFF;    }    curr_event_samples += samples_to_do;    curr_tick += tick;    ev.type = ME_NONE;    seq_play_event(&ev);}static int tick2sample(int tick){    int32 samples, cum;    samples = sample_increment * tick;    cum = sample_correction * tick;    if(cum & 0xFFFF0000)	samples += ((sample_cum >> 16) & 0xFFFF);    return samples;}int time2tick(double sec){    return (int)(sec * curr_timebase);}static void stop_playing(void){    if(upper_voices)    {	MidiEvent ev;	ev.type = ME_EOT;	ev.a = 0;	ev.b = 0;	seq_play_event(&ev);	aq_flush(0);    }}static int do_control_command(void);static int do_control_command_nonblock(void);static int do_sequencer(void);static void do_chn_voice(uint8 *);static void do_chn_common(uint8 *);static void do_timing(uint8 *);static void do_sysex(uint8 *, int len);static void do_extended(uint8 *);static void do_timeout(void);static void server_seq_sync(double tm);static uint8 data_buffer[BUFSIZ];static int data_buffer_len;static void doit(void){    memset(&control_fd_buffer, 0, sizeof(control_fd_buffer));    control_fd_buffer.fd = control_fd;    send_status(220, "TiMidity++ v%s ready", timidity_version);/*    while(data_fd != -1 && control_fd != -1) */    while(control_fd != -1)    {	fd_set fds;	int n, maxfd;	if(data_fd == -1)	{	    if(do_control_command())		break;	}	else	{	    long usec;	    FD_ZERO(&fds);	    FD_SET(control_fd, &fds);	    FD_SET(data_fd, &fds);	    if(control_fd > data_fd)		maxfd = control_fd;	    else		maxfd = data_fd;	    if(data_fd != -1)	    {		    double wait_time;		    int32 filled;		    filled = aq_filled();		    if(!tmr_running && filled <= 0)			usec = -1;		    else		    {			wait_time = (double)filled / play_mode->rate			    - low_time_at;			if(wait_time <= 0)			    usec = 0;			else			    usec = (long)(wait_time * 1000000);		    }	    }	    else		usec = -1;	    if(usec >= 0)	    {		struct timeval timeout;		timeout.tv_sec = usec / 1000000;		timeout.tv_usec = usec % 1000000;		n = select(maxfd + 1, &fds, NULL, NULL, &timeout);	    }	    else		n = select(maxfd + 1, &fds, NULL, NULL, NULL);	    if(n < 0)	    {		perror("select");		break;	    }	    if(n == 0)	    {		if(ctl.verbosity >= VERB_DEBUG)		{		    putchar(',');		    fflush(stdout);		}		do_timeout();		continue;	    }	    if(control_fd != -1 && FD_ISSET(control_fd, &fds))	    {		if(do_control_command())		{		    close(control_fd);		    control_fd = -1;		}	    }	    else if(data_fd != -1 && FD_ISSET(data_fd, &fds))	    {		if(do_sequencer())		{		    close(data_fd);		    data_fd = -1;		    send_status(403, "Data connection is closed");		}	    }	}    }    if(data_fd != -1)	stop_playing();}static void do_timeout(void){    double fill_time;    if(data_fd == -1 || !IS_STREAM_TRACE)	return;    aq_add(NULL, 0);    fill_time = high_time_at - (double)aq_filled() / play_mode->rate;    if(fill_time <= 0)	return;    if(tmr_running)	add_tick(time2tick(fill_time));    else    {	MidiEvent ev;	event_time_offset += (int32)(fill_time *				     play_mode->rate);	ev.time = curr_event_samples + event_time_offset;	ev.type = ME_NONE;	play_event(&ev);    }}/* -1=error, 0=success, 1=connection-closed */static int data_flush(int discard){    fd_set fds;    char buff[BUFSIZ];    struct timeval timeout;    int n;    while(1)    {	FD_ZERO(&fds);	FD_SET(data_fd, &fds);	timeout.tv_sec = 0;	if(discard)	    timeout.tv_usec = 100000;	else	    timeout.tv_usec = 0;	if((n = select(data_fd + 1, &fds, NULL, NULL, &timeout)) < 0)	{	    perror("select");	    return -1;	}	if(n == 0)	    break;	if(discard)	{	    if((n = read(data_fd, buff, sizeof(buff))) < 0)	    {		perror("read");		return -1;	    }	    if(n == 0)		return 1;	}	else	{	    int status;	    if((status = do_sequencer()) != 0)		return status;	}    }    return 0;}static void server_seq_sync(double tm){    double t;    aq_soft_flush();    t = (double)aq_filled() / play_mode->rate;    if(t > tm)	usleep((unsigned long)((t - tm) * 1000000));}static void server_reset(void){    playmidi_stream_init();    if(free_instruments_afterwards)	free_instruments(0);    data_buffer_len = 0;    do_sysex(NULL, 0); /* Initialize SysEx buffer */    low_time_at = DEFAULT_LOW_TIMEAT;    high_time_at = DEFAULT_HIGH_TIMEAT;    reduce_voice_threshold = 0; /* Disable auto reduction voice */    compute_sample_increment();    tmr_reset();    tmr_running = 0;    start_time = get_current_calender_time();}/* -1=error, 0=success, 1=connection-closed */static int do_control_command(void){    int status;    char *params[MAX_GETCMD_PARAMS];    int nparams;    int i;    if((status = control_getcmd(params, &nparams)) == -1)	return -1;    if(status == 1)    {	send_status(500, "Error");	return 1;    }    if(nparams == 0 ||  *params == NULL || **params == '\0')	return 0;    for(i = 0; cmd_table[i].cmd; i++)	if(strcasecmp(params[0], cmd_table[i].cmd) == 0)	{	    if(nparams < cmd_table[i].minarg)		return send_status(501, "'%s': Arguments is too few",				   params[0]);	    if(nparams > cmd_table[i].maxarg)		return send_status(501, "'%s': Arguments is too many",				   params[0]);	    return cmd_table[i].proc(nparams, params);	}    return send_status(500, "'%s': command not understood.", params[0]);}static int cmd_help(int argc, char **argv){    int i;    if(send_status(200, "Help ok"))	return -1;    for(i = 0; cmd_table[i].cmd; i++)    {	if(fdputs(cmd_table[i].help, control_fd))	    return -1;	if(fdputs("\n", control_fd))	    return -1;    }    return fdputs(".\n", control_fd);}static int cmd_open(int argc, char **argv){    int sock;    struct sockaddr_in in;    int addrlen;    int port;    if(data_fd != -1)	return send_status(125, "Data connection is already opened");    if(strcasecmp(argv[1], "lsb") == 0)	is_lsb_data = 1;    else if(strcasecmp(argv[1], "msb") == 0)	is_lsb_data = 0;    else	return send_status(502, "OPEN: Invalid argument: %s", argv[1]);    port = data_port;    if((sock = pasv_open(&port)) == -1)	return send_status(511, "Can't open data connection");    addrlen = sizeof(in);    memset(&in, 0, addrlen);    send_status(200, "%d is ready acceptable", port);    alarm(SIG_TIMEOUT_SEC);    data_fd = accept(sock, (struct sockaddr *)&in, &addrlen);    alarm(0);    if(data_fd < 0)    {	send_status(512, "Accept error");	close(sock);	return 0;    }    close(sock);    if(control_client.sin_addr.s_addr != in.sin_addr.s_addr)	return send_status(513, "Security violation:  Address mismatch");    send_status(200, "Ready data connection");    data_buffer_len = 0;    do_sysex(NULL, 0); /* Initialize SysEx buffer */    tmr_reset();    return 0;}static int cmd_close(int argc, char **argv){    if(data_fd != -1)    {	close(data_fd);	data_fd = -1;	return send_status(302, "Data connection is closed");    }    return send_status(302, "Data connection is already closed");}static int cmd_queue(int argc, char **argv){    int32 qsamples;    aq_add(NULL, 0); /* Update software queue */    if(!aq_fill_buffer_flag)	qsamples = aq_soft_filled() + aq_filled();    else	qsamples = 0;    return send_status(200, "%f sec", (double)qsamples / play_mode->rate);}static int cmd_maxqueue(int argc, char **argv){    return send_status(200, "%f sec",		       (double)aq_get_dev_queuesize() / play_mode->rate);}static int cmd_time(int argc, char **argv){    return send_status(200, "%f sec", (double)aq_samples());}static int cmd_quit(int argc, char **argv){    send_status(200, "Bye");    return 1;}static int cmd_timebase(int argc, char **argv){    int i;    if(argc == 1)	return send_status(200, "%d OK", curr_timebase);    i = atoi(argv[1]);    if(i < 1)	i = 1;    else if(i > 1000)	i = 1000;    if(i != curr_timebase)    {	curr_timebase = i;	compute_sample_increment();	tick_offs = curr_tick;	start_time = get_current_calender_time();    }    return send_status(200, "OK");}static int cmd_patch(int argc, char **argv){    int dr, bank, prog;    if(strcasecmp(argv[1], "drumset") == 0)	dr = 1;    else if(strcasecmp(argv[1], "bank") == 0)	dr = 0;    else	return send_status(502, "PATCH: Invalid argument: %s", argv[1]);     bank = atoi(argv[2]);    prog = atoi(argv[3]);    if(bank < 0 || bank > 127 || prog < 0 || prog > 127)	return send_status(502, "PATCH: Invalid argument");     if(play_midi_load_instrument(dr, bank, prog) == NULL)	return send_status(514, "PATCH: Can't load the patch");    return send_status(200, "OK");}static int cmd_reset(int argc, char **argv){    int status;    if(data_fd >= 0)    {	stop_playing();	if((status = data_flush(1)) != 0)	    return status;    }    server_reset();    return send_status(200, "OK");}static int cmd_autoreduce(int argc, char **argv){    if(strcasecmp(argv[1], "on") == 0)    {	if(argc == 3)	    reduce_voice_threshold = atoi(argv[2]);	else	    reduce_voice_threshold = -1;    }    else if(strcasecmp(argv[1], "off") == 0)	reduce_voice_threshold = 0;    else	return send_status(502, "AUTOREDUCE: Invalid argument: %s",			   argv[1]);    return send_status(200, "OK");}static int cmd_setbuf(int argc, char **argv){    low_time_at = atof(argv[1]);    high_time_at = atof(argv[1]);    return send_status(200, "OK");}static int cmd_nop(int argc, char **argv){    return send_status(200, "NOP OK");}static int do_control_command_nonblock(void){    struct timeval timeout;    int n;    fd_set fds;    if(control_fd == -1)	return 1;    FD_ZERO(&fds);    FD_SET(control_fd, &fds);    timeout.tv_sec = 0;    timeout.tv_usec = 0;    n = select(control_fd + 1, &fds, NULL, NULL, &timeout);    if(n > 0 && FD_ISSET(control_fd, &fds))	return do_control_command();    return 0;}static int fdgets(char *buff, size_t buff_size, struct fd_read_buffer *p){    int n, len, count, size, fd;    char *buff_endp = buff + buff_size - 1, *pbuff, *beg;    fd = p->fd;    if(buff_size == 0)	return 0;    else if(buff_size == 1) /* buff == buff_endp */    {	*buff = '\0';	return 0;    }    len = 0;    count = p->count;    size = p->size;    pbuff = p->buff;    beg = buff;    do    {	if(count == size)	{	    if((n = read(fd, pbuff, BUFSIZ)) <= 0)	    {		*buff = '\0';		if(n == 0)		{		    p->count = p->size = 0;		    return buff - beg;		}

⌨️ 快捷键说明

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