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

📄 rtsyn_common.c

📁 linux上播放midi音乐,但是要一些设置.可网上查找. 软件名称: TiMidity++-2.13.0.tar
💻 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    rtsyn_common.c        Copyright (c) 2003  Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>    I referenced following sources.        alsaseq_c.c - ALSA sequencer server interface            Copyright (c) 2000  Takashi Iwai <tiwai@suse.de>        readmidi.c*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include "interface.h"#include <stdio.h>#include <stdarg.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/types.h>#ifdef TIME_WITH_SYS_TIME#include <sys/time.h>#endif#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <math.h>#include <signal.h>#include "server_defs.h"#ifdef __W32__#include <windows.h>#endif#include "timidity.h"#include "common.h"#include "controls.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "recache.h"#include "output.h"#include "aq.h"#include "timer.h"#include "rtsyn.h"//int seq_quit;int rtsyn_system_mode=DEFAULT_SYSTEM_MODE;static int32 event_time_offset;static double starttime;double rtsyn_reachtime;static int time_advance;static int set_time_first=2;//acitive sensingstatic int active_sensing_flag=0;static double active_sensing_time=0;//timer interrupt#ifdef USE_WINSYN_TIMER_Irtsyn_mutex_t timerMUTEX;#ifdef __W32__MMRESULT timerID;#else pthread_t timer_thread;int thread_on_f=0;#endif#endif#define EX_RESET_NO 7static char sysex_resets[EX_RESET_NO][11]={		'\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',		'\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00',		'\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00',		'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7',		'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7',		'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7',		'\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' };/*#define EX_RESET_NO 9static char sysex_resets[EX_RESET_NO][11]={	'\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off	'\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00', //gm1	'\xf0','\x7e','\x7f','\x09','\x02','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off	'\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00', //gm2	'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7', //GS	'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x7f','\x41','\xf7', //GS off	'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7', //88	'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7', //88	'\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00'  //XG on	};*/static void seq_set_time(MidiEvent *ev);void rtsyn_gm_reset(){	MidiEvent ev;	rtsyn_server_reset();	ev.type=ME_RESET;	ev.a=GM_SYSTEM_MODE;	rtsyn_play_event(&ev);}void rtsyn_gs_reset(){	MidiEvent ev;	rtsyn_server_reset();	ev.type=ME_RESET;	ev.a=GS_SYSTEM_MODE;	rtsyn_play_event(&ev);}void rtsyn_xg_reset(){	MidiEvent ev;	rtsyn_server_reset();	ev.type=ME_RESET;	ev.a=XG_SYSTEM_MODE;	ev.time=0;	rtsyn_play_event(&ev);}void rtsyn_normal_reset(){	MidiEvent ev;	rtsyn_server_reset();	ev.type=ME_RESET;	ev.a=rtsyn_system_mode;	rtsyn_play_event(&ev);}void rtsyn_gm_modeset(){	MidiEvent ev;	rtsyn_server_reset();	rtsyn_system_mode=GM_SYSTEM_MODE;	ev.type=ME_RESET;	ev.a=GM_SYSTEM_MODE;	rtsyn_play_event(&ev);	change_system_mode(rtsyn_system_mode);}void rtsyn_gs_modeset(){	MidiEvent ev;	rtsyn_server_reset();	rtsyn_system_mode=GS_SYSTEM_MODE;	ev.type=ME_RESET;	ev.a=GS_SYSTEM_MODE;	rtsyn_play_event(&ev);	change_system_mode(rtsyn_system_mode);}void rtsyn_xg_modeset(){	MidiEvent ev;	rtsyn_server_reset();	rtsyn_system_mode=XG_SYSTEM_MODE;	ev.type=ME_RESET;	ev.a=XG_SYSTEM_MODE;	rtsyn_play_event(&ev);	change_system_mode(rtsyn_system_mode);}void rtsyn_normal_modeset(){	MidiEvent ev;	rtsyn_server_reset();	rtsyn_system_mode=DEFAULT_SYSTEM_MODE;	ev.type=ME_RESET;	ev.a=GS_SYSTEM_MODE;	rtsyn_play_event(&ev);	change_system_mode(rtsyn_system_mode);}#ifdef USE_WINSYN_TIMER_I#ifdef __W32__VOID CALLBACK timercalc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dummy1, DWORD dummy2){	MidiEvent ev;	double time_div, currenttime;		rtsyn_mutex_lock(timerMUTEX);	currenttime=get_current_calender_time();	time_div=currenttime-starttime;	if( time_div > 1.0/TICKTIME_HZ*2.0){		time_div= 1.0/TICKTIME_HZ-3/(play_mode->rate);	}	ev.time= ((double)current_sample			+ (play_mode->rate)*time_div+0.5);	starttime=currenttime;	ev.type = ME_NONE;	play_event(&ev);//	compute_data(tmdy_struct,(tmdy_struct->output->play_mode->rate)*time_div);	aq_fill_nonblocking();	rtsyn_reachtime=currenttime +  (double)(1.0f/TICKTIME_HZ);	rtsyn_mutex_unlock(timerMUTEX);	return;}#elsevoid *timercalc(void *arg){ 	MidiEvent ev;	unsigned int slt;	double reachtime,delay;	delay=(double)(1.0/TICKTIME_HZ);	while(thread_on_f==1){				rtsyn_mutex_lock(timerMUTEX);		reachtime=get_current_calender_time()+delay;		ev.type = ME_NONE;		seq_set_time(&ev);		play_event(&ev);		aq_fill_nonblocking();		rtsyn_mutex_unlock(timerMUTEX);		do{			sleep(0);		}while(get_current_calender_time()<reachtime);	}	return NULL;}#endif#endifvoid rtsyn_init(void){	int i,j;		/* set constants */	opt_realtime_playing = 1; /* Enable loading patch while playing */	allocate_cache_size = 0; /* Don't use pre-calclated samples */	auto_reduce_polyphony = 0;	current_keysig = (opt_init_keysig == 8) ? 0 : opt_init_keysig;	note_key_offset = 0;	time_advance=play_mode->rate/TICKTIME_HZ*2;	if (!(play_mode->encoding & PE_MONO))		time_advance >>= 1;	if (play_mode->encoding & PE_24BIT)		time_advance /= 3;	else if (play_mode->encoding & PE_16BIT)		time_advance >>= 1;	if (opt_force_keysig != 8) {		i = current_keysig + ((current_keysig < 8) ? 7 : -6);		j = opt_force_keysig + ((current_keysig < 8) ? 7 : 10);		while (i != j && i != j + 12) {			if (++note_key_offset > 6)				note_key_offset -= 12;			i += (i > 10) ? -5 : 7;		}	}	i = current_keysig + ((current_keysig < 8) ? 7 : -9), j = 0;	while (i != 7 && i != 19)		i += (i < 7) ? 5 : -7, j++;	j += note_key_offset, j -= floor(j / 12.0) * 12;	current_freq_table = j;	#ifdef USE_WINSYN_TIMER_I	rtsyn_mutex_init(timerMUTEX);#ifdef __W32__	timeBeginPeriod(1);	{		DWORD data = 0;		UINT delay;		delay=(1000/TICKTIME_HZ);		 				timerID = timeSetEvent( delay, 0, timercalc, data,			TIME_PERIODIC | TIME_CALLBACK_FUNCTION );        if( !timerID ){        	ctl->cmsg(  CMSG_ERROR, VERB_NORMAL,"Fail to setup Timer Interrupt (winsyn) \n");        }	}#else	thread_on_f=1;	if(0!=pthread_create(&timer_thread,NULL,timercalc,NULL)){        	ctl->cmsg(  CMSG_ERROR, VERB_NORMAL,"Fail to setup Timer Interrupt (winsyn) \n");	}#endif#endif	rtsyn_server_reset();}void rtsyn_close(void){#ifdef USE_WINSYN_TIMER_I#ifdef __W32__	timeKillEvent( timerID );	timeEndPeriod(1);#else	thread_on_f=0;	pthread_join(timer_thread, NULL);#endif	rtsyn_mutex_destroy(timerMUTEX);#endif }void rtsyn_play_event(MidiEvent *ev){  int gch;  int32 cet;#ifdef USE_WINSYN_TIMER_I	rtsyn_mutex_lock(timerMUTEX);#endif 	gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);	if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){//    if ( !seq_quit ) {			ev->time=0;			play_event(ev);//		}	}#ifdef USE_WINSYN_TIMER_I	rtsyn_mutex_unlock(timerMUTEX);#endif }void rtsyn_reset(void){		rtsyn_stop_playing();#ifdef USE_WINSYN_TIMER_I	        rtsyn_mutex_lock(timerMUTEX);#endif		free_instruments(0);        //also in rtsyn_server_reset		free_global_mblock();#ifdef USE_WINSYN_TIMER_I	        rtsyn_mutex_unlock(timerMUTEX);#endif		rtsyn_server_reset();//		printf("system reseted\n");}void rtsyn_server_reset(void){#ifdef USE_WINSYN_TIMER_I	rtsyn_mutex_lock(timerMUTEX);#endif 	play_mode->close_output();	// PM_REQ_PLAY_START wlll called in playmidi_stream_init()	play_mode->open_output();	// but w32_a.c does not have it.	readmidi_read_init();	playmidi_stream_init();	starttime=get_current_calender_time();	reduce_voice_threshold = 0; // * Disable auto reduction voice *	auto_reduce_polyphony = 0;	event_time_offset = 0;#ifdef USE_WINSYN_TIMER_I	rtsyn_mutex_unlock(timerMUTEX);#endif }void rtsyn_stop_playing(void){	if(upper_voices) {		MidiEvent ev;		ev.type = ME_EOT;		ev.a = 0;		ev.b = 0;		rtsyn_play_event(&ev);#ifdef USE_WINSYN_TIMER_I	        rtsyn_mutex_lock(timerMUTEX);#endif		aq_flush(1);#ifdef USE_WINSYN_TIMER_I		        rtsyn_mutex_unlock(timerMUTEX);#endif	}}extern int32 current_sample;extern FLOAT_T midi_time_ratio;extern int volatile stream_max_compute;static void seq_set_time(MidiEvent *ev){	double currenttime, time_div;		currenttime=get_current_calender_time();	time_div=currenttime-starttime;	ev->time=((double) current_sample			+ (play_mode->rate)*time_div+0.5);	starttime=currenttime;		rtsyn_reachtime=currenttime +  (double)(1.0f/TICKTIME_HZ);}#if 0static void seq_set_time(MidiEvent *ev){	double past_time,btime;	static int shift=0;	if(set_time_first==2){		starttime=get_current_calender_time()-(double)current_sample/(double)play_mode->rate;	}	past_time = (int32)((get_current_calender_time() - starttime)*play_mode->rate);	//	printf("%f,%f\n",(double)past_time,(  (double)current_sample-(double)past_time )  );	if (set_time_first==1){		shift=(double)past_time-(double)current_sample;///		printf("%d\n",shift);	}	if (set_time_first>0) set_time_first--;	event_time_offset=play_mode->rate/TICKTIME_HZ;	ev->time = past_time;	if(set_time_first==0 && (past_time-current_sample>stream_max_compute*play_mode->rate/1000)){ 		starttime=get_current_calender_time()-(double)(current_sample+shift)/(double)play_mode->rate;		ev->time=current_sample+shift;	}	ev->time += (int32)event_time_offset;		rtsyn_reachtime=get_current_calender_time()+  (double)(1.0f/TICKTIME_HZ);	#if 0	btime = (double)((ev->time-current_sample/midi_time_ratio)/play_mode->rate);	btime *= 1.01; /* to be sure */	aq_set_soft_queue(btime, 0.0);#endif}#endifvoid rtsyn_play_calculate(){	MidiEvent ev;#ifndef USE_WINSYN_TIMER_I		ev.type = ME_NONE;	seq_set_time(&ev);	play_event(&ev);	aq_fill_nonblocking();#endif		if(active_sensing_flag==~0 && (get_current_calender_time() > active_sensing_time+0.5)){//normaly acitive sensing expiering time is 330ms(>300ms) but this loop is heavy		play_mode->close_output();		play_mode->open_output();		ctl->cmsg(  CMSG_ERROR, VERB_NORMAL,"Active Sensing Expired\n");		active_sensing_flag=0;	}}	int rtsyn_play_one_data (int port, int32 dwParam1){	MidiEvent ev;	ev.type = ME_NONE;	ev.channel = dwParam1 & 0x0000000f;	ev.channel = ev.channel+port*16;	ev.a = (dwParam1 >> 8) & 0xff;	ev.b = (dwParam1 >> 16) & 0xff;	switch ((int) (dwParam1 & 0x000000f0)) {	case 0x80:		ev.type = ME_NOTEOFF;//		rtsyn_play_event(&ev);		break;	case 0x90:		ev.type = (ev.b) ? ME_NOTEON : ME_NOTEOFF;//		rtsyn_play_event(&ev);		break;	case 0xa0:		ev.type = ME_KEYPRESSURE;//		rtsyn_play_event(&ev);		break;	case 0xb0:		if (! convert_midi_control_change(ev.channel, ev.a, ev.b, &ev))		ev.type = ME_NONE;		break;	case 0xc0:		ev.type = ME_PROGRAM;//		rtsyn_play_event(&ev);		break;	case 0xd0:		ev.type = ME_CHANNEL_PRESSURE;//		rtsyn_play_event(&ev);		break;	case 0xe0:		ev.type = ME_PITCHWHEEL;//		rtsyn_play_event(&ev);		break;	case 0xf0:#ifdef IA_PORTMIDISYN		if ( (dwParam1 & 0x000000ff) == 0xf0) {			//SysEx			return 1;		}#endif		if ((dwParam1 & 0x000000ff) == 0xf2) {			ev.type = ME_PROGRAM;//			rtsyn_play_event(&ev);		}#if 0		if ((dwParam1 & 0x000000ff) == 0xf1)			//MIDI Time Code Qtr. Frame (not need)			printf("MIDI Time Code Qtr\n");		if ((dwParam1 & 0x000000ff) == 0xf3)			//Song Select(Song #) (not need)		if ((dwParam1 & 0x000000ff) == 0xf6)			//Tune request (not need)			printf("Tune request\n");		if ((dwParam1 & 0x000000ff) == 0xf8)			//Timing Clock (not need)			printf("Timing Clock\n");		if ((dwParam1&0x000000ff)==0xfa)			//Start		if ((dwParam1 & 0x000000ff) == 0xfb)			//Continue		if ((dwParam1 & 0x000000ff) == 0xfc) {			//Stop			printf("Stop\n");		}#endif		if ((dwParam1 & 0x000000ff) == 0xfe) {			//Active Sensing//			printf("Active Sensing\n");			active_sensing_flag = ~0;			active_sensing_time = get_current_calender_time();		}		if ((dwParam1 & 0x000000ff) == 0xff) {			//System Reset			printf("System Reset\n");		}		break;	default://		printf("Unsup/ed event %d\n", aevp->type);		break;	}	if (ev.type != ME_NONE) {		rtsyn_play_event(&ev);	}	return 0;}void rtsyn_play_one_sysex (char *sysexbuffer, int exlen ){	int i,j,chk,ne;	MidiEvent ev;	MidiEvent evm[260];	if(sysexbuffer[exlen-1] == '\xf7'){            // I don't konw why this need		for(i=0;i<EX_RESET_NO;i++){			chk=0;			for(j=0;(j<exlen)&&(j<11);j++){				if(chk==0 && sysex_resets[i][j]!=sysexbuffer[j]){					chk=~0;				}			}			if(chk==0){				 rtsyn_server_reset();			}		}/*		printf("SyeEx length=%x bytes \n", exlen);		for(i=0;i<exlen;i++){			printf("%x ",sysexbuffer[i]);		}		printf("\n");*/		if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){			if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){				ev.a=rtsyn_system_mode;				change_system_mode(rtsyn_system_mode);				rtsyn_play_event(&ev);			}else{				rtsyn_play_event(&ev);			}		}		if(ne=parse_sysex_event_multi(sysexbuffer+1,exlen-1, evm)){			for (i = 0; i < ne; i++){					rtsyn_play_event(&evm[i]);			}		}	}}

⌨️ 快捷键说明

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