📄 xaw_c.c
字号:
static int ctl_read(int32 *valp) { if (a_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 init_number_of_files, char *init_list_of_files[]) { int current_no,command=RC_NONE,i,j; int32 val; char *p; /* Wait prepare 'interface' */ a_pipe_read(local_buf,sizeof(local_buf)); if (strcmp("READY",local_buf)) return; xaw_ready=1; sprintf(local_buf,"%d", (opt_modulation_wheel<<MODUL_N) | (opt_portamento<<PORTA_N) | (opt_nrpn_vibrato<<NRPNV_N) | (opt_reverb_control<<REVERB_N) | (opt_channel_pressure<<CHPRESSURE_N) | (opt_overlap_voice_allow<<OVERLAPV_N) | (opt_trace_text_meta_event<<TXTMETA_N)); a_pipe_write(local_buf); sprintf(local_buf,"%d",opt_chorus_control); a_pipe_write(local_buf); /* Make title string */ titles=(char **)safe_malloc(init_number_of_files*sizeof(char *)); list_of_files=(char **)safe_malloc(init_number_of_files*sizeof(char *)); for (i=0,j=0;i<init_number_of_files;i++) { if(check_midi_file(init_list_of_files[i]) >= 0) { p=strrchr(init_list_of_files[i],'/'); if (p==NULL) { p=safe_strdup(init_list_of_files[i]); } else p++; list_of_files[j]= safe_strdup(init_list_of_files[i]); titles[j]=(char *)safe_malloc(sizeof(char)*(strlen(p)+ 9)); sprintf(titles[j],"%d. %s",j+1,p); j++; number_of_files = j; } } titles=(char **)safe_realloc(titles,init_number_of_files*sizeof(char *)); list_of_files=(char **)safe_realloc(list_of_files,init_number_of_files*sizeof(char *)); /* Send title string */ sprintf(local_buf,"%d",number_of_files); a_pipe_write(local_buf); for (i=0;i<number_of_files;i++) a_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; if(number_of_files!=0){ snprintf(local_buf,sizeof(local_buf),"E %s",titles[file_table[0]]); a_pipe_write(local_buf); command=ctl_blocking_read(&val); } /* Main loop */ for (;;) { /* Play file */ if (command==RC_LOAD_FILE&&number_of_files!=0) { char *title; snprintf(local_buf,sizeof(local_buf),"E %s",titles[file_table[current_no]]); a_pipe_write(local_buf); if((title = get_midi_title(list_of_files[file_table[current_no]])) == NULL) title = list_of_files[file_table[current_no]]; snprintf(local_buf,sizeof(local_buf),"e %s", title); a_pipe_write(local_buf); command=play_midi_file(list_of_files[file_table[current_no]]); } else { if (command==RC_CHANGE_VOLUME) amplitude+=val; if (command==RC_JUMP) ; if (command==RC_TOGGLE_SNDSPEC) ; /* Quit timidity*/ if (exitflag & EXITFLG_QUIT) return; /* Stop playing */ if (command==RC_QUIT) { sprintf(local_buf,"T 00:00"); a_pipe_write(local_buf); /* Shuffle the table */ if (randomflag) { if(number_of_files == 0) { randomflag=0; continue; } 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; snprintf(local_buf,sizeof(local_buf),"E %s",titles[file_table[current_no]]); a_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; } else if (exitflag & EXITFLG_AUTOQUIT) { return; /* Repeat */ } else if (repeatflag) { current_no=0; command=RC_LOAD_FILE; continue; /* Off the play button */ } else { a_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 ----- */static int pipe_in_fd,pipe_out_fd;extern void a_start_interface(int);static void a_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]; a_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 a_pipe_write(char *buf) { write(pipe_out_fd,buf,strlen(buf)); write(pipe_out_fd,"\n",1);}static int a_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 a_pipe_read(char *buf,int bufsize) { int i; bufsize--; for (i=0;i<bufsize;i++) { ssize_t len = read(pipe_in_fd,buf+i,1); if (len != 1) { perror("CONNECTION PROBLEM WITH XAW PROCESS"); exit(1); } if (buf[i]=='\n') break; } buf[i]=0; return 0;}int a_pipe_nread(char *buf, int n){ int i, j; j = 0; while(n > 0 && (i = read(pipe_in_fd, buf + j, n - j)) > 0) j += i; return j;}static void a_pipe_write_msg(char *msg){ int msglen; char buf[2 + sizeof(int)], *p, *q; /* strip '\r' */ p = q = msg; while(*q) { if(*q != '\r') *p++ = *q; q++; } *p = '\0'; msglen = strlen(msg) + 1; /* +1 for '\n' */ buf[0] = 'L'; buf[1] = '\n'; memcpy(buf + 2, &msglen, sizeof(int)); write(pipe_out_fd, buf, sizeof(buf)); write(pipe_out_fd, msg, msglen - 1); write(pipe_out_fd, "\n", 1);}static voidctl_note(int status, int ch, int note, int velocity){ char c; if(ch >= MAX_XAW_MIDI_CHANNELS) return; if(!ctl.trace_playing || midi_trace.flush_flag) return; c = '.'; switch(status) { case VOICE_ON: c = '*'; break; case VOICE_SUSTAINED: c = '&'; break; case VOICE_FREE: case VOICE_DIE: case VOICE_OFF: default: break; } snprintf(local_buf,sizeof(local_buf),"Y%c%c%03d%d",ch+'A',c,(unsigned char)note,velocity); a_pipe_write(local_buf);}static void ctl_program(int ch, int val, void *comm){ if(ch >= MAX_XAW_MIDI_CHANNELS) return; if(!ctl.trace_playing) return; if(!IS_CURRENT_MOD_FILE) val += progbase; sprintf(local_buf, "PP%c%d", ch+'A', val); a_pipe_write(local_buf); if (comm != NULL) { sprintf(local_buf, "I%c%s", ch+'A', (char *)comm); if (ISDRUMCHANNEL(ch)) sprintf(local_buf, "I%c%s", ch+'A', (!strlen((char *)comm))? "<drum>":(char *)comm); a_pipe_write(local_buf); }}static void ctl_drumpart(int ch, int is_drum){ if(ch >= MAX_XAW_MIDI_CHANNELS) return; if(!ctl.trace_playing) return; sprintf(local_buf, "i%c%c", ch+'A', is_drum+'A');; a_pipe_write(local_buf);}static void ctl_event(CtlEvent *e){ switch(e->type) { case CTLE_LOADING_DONE: break; case CTLE_CURRENT_TIME: ctl_current_time((int)e->v1, (int)e->v2); break; case CTLE_PLAY_START: ctl_total_time((int)e->v1); break; case CTLE_PLAY_END: break; case CTLE_TEMPO: break; case CTLE_METRONOME: break; case CTLE_NOTE: ctl_note((int)e->v1, (int)e->v2, (int)e->v3, (int)e->v4); break; case CTLE_PROGRAM: ctl_program((int)e->v1, (int)e->v2, (char *)e->v3); break; case CTLE_DRUMPART: ctl_drumpart((int)e->v1, (int)e->v2); break; case CTLE_VOLUME: ctl_volume((int)e->v1, (int)e->v2); break; case CTLE_EXPRESSION: ctl_expression((int)e->v1, (int)e->v2); break; case CTLE_PANNING: ctl_panning((int)e->v1, (int)e->v2); break; case CTLE_SUSTAIN: ctl_sustain((int)e->v1, (int)e->v2); break; case CTLE_PITCH_BEND: ctl_pitch_bend((int)e->v1, (int)e->v2); break; case CTLE_MOD_WHEEL: ctl_pitch_bend((int)e->v1, e->v2 ? -1 : 0x2000); break; case CTLE_CHORUS_EFFECT: set_otherinfo((int)e->v1, (int)e->v2, 'c'); break; case CTLE_REVERB_EFFECT: set_otherinfo((int)e->v1, (int)e->v2, 'r'); break; case CTLE_LYRIC: ctl_lyric((int)e->v1); break; case CTLE_MASTER_VOLUME: ctl_master_volume((int)e->v1); break; case CTLE_REFRESH: ctl_refresh(); break; case CTLE_RESET: ctl_reset(); break; }}static void ctl_refresh(void){}static void set_otherinfo(int ch, int val, char c) { if(!ctl.trace_playing) return; if(ch >= MAX_XAW_MIDI_CHANNELS) return; sprintf(local_buf, "P%c%c%d", c, ch+'A', val); a_pipe_write(local_buf);}static void ctl_reset(void){ int i; if(!ctl.trace_playing) return; indicator_last_update = get_current_calender_time(); for (i=0; i<MAX_XAW_MIDI_CHANNELS; i++) { if(ISDRUMCHANNEL(i)) { ctl_program(i, channel[i].bank, channel_instrum_name(i)); if (opt_reverb_control) set_otherinfo(i, get_reverb_level(i), 'r'); } else { ToneBank *bank; int b; ctl_program(i, channel[i].program, channel_instrum_name(i)); b = channel[i].bank; if((bank = tonebank[b]) == NULL || bank->tone[channel[i].program].instrument == NULL) { b = 0; bank = tonebank[0]; } set_otherinfo(i, channel[i].bank, 'b'); if (opt_reverb_control) set_otherinfo(i, get_reverb_level(i), 'r'); if(opt_chorus_control) set_otherinfo(i, get_chorus_level(i), 'c'); } ctl_volume(i, channel[i].volume); ctl_expression(i, channel[i].expression); ctl_panning(i, channel[i].panning); ctl_sustain(i, channel[i].sustain); if(channel[i].pitchbend == 0x2000 && channel[i].mod.val > 0) ctl_pitch_bend(i, -1); else ctl_pitch_bend(i, channel[i].pitchbend); } sprintf(local_buf, "R"); a_pipe_write(local_buf); }static void update_indicator(void){ double t, diff; if(!ctl.trace_playing) return; t = get_current_calender_time(); diff = t - indicator_last_update; if(diff > XAW_UPDATE_TIME) { sprintf(local_buf, "U"); a_pipe_write(local_buf); indicator_last_update = t; }}/* * interface_<id>_loader(); */ControlMode *interface_a_loader(void){ return &ctl;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -