📄 server_c.c
字号:
return -1; /* < 0 error */ } count = p->count = 0; size = p->size = n; } *buff++ = pbuff[count++]; } while(*(buff - 1) != '\n' && buff != buff_endp); *buff = '\0'; p->count = count; return buff - beg;}static int fdputs(char *s, int fd){ if(write(fd, s, strlen(s)) == -1) return -1; return 0;}#ifdef LITTLE_ENDIANstatic uint32 data2long(uint8* data){ uint32 x; memcpy(&x, data, sizeof(x)); if(!is_lsb_data) x = XCHG_LONG(x); return x;}static uint16 data2short(uint8* data){ uint16 x; memcpy(&x, data, sizeof(x)); if(!is_lsb_data) x = XCHG_SHORT(x); return x;}#elsestatic uint32 data2long(uint8* data){ uint32 x; memcpy(&x, data, sizeof(x)); if(is_lsb_data) x = XCHG_LONG(x); return x;}static uint16 data2short(uint8* data){ uint16 x; memcpy(&x, data, sizeof(x)); if(is_lsb_data) x = XCHG_SHORT(x); return x;}#endifstatic int do_sequencer(void){ int n, offset; MidiEvent ev; n = read(data_fd, data_buffer + data_buffer_len, sizeof(data_buffer) - data_buffer_len); if(n <= 0) { stop_playing(); return n; }#ifdef DEBUG_DUMP_SEQ { int i; for(i = 0; i < n; i++) printf("%02x", data_buffer[data_buffer_len + i]); putchar('\n'); }#endif /* DEBUG_DUMP_SEQ */ data_buffer_len += n; offset = 0; while(offset < data_buffer_len) { int cmd; cmd = data_buffer[offset];#define READ_NEEDBUF(x) if(offset + x > data_buffer_len) goto done;#define READ_ADVBUF(x) offset += x; switch(cmd) { case EV_CHN_VOICE: READ_NEEDBUF(8); do_chn_voice(data_buffer + offset); READ_ADVBUF(8); break; case EV_CHN_COMMON: READ_NEEDBUF(8); do_chn_common(data_buffer + offset); READ_ADVBUF(8); break; case EV_TIMING: READ_NEEDBUF(8); do_timing(data_buffer + offset); READ_ADVBUF(8); break; case EV_SYSEX: READ_NEEDBUF(8); do_sysex(data_buffer + offset + 2, 6); READ_ADVBUF(8); break; case SEQ_MIDIPUTC: if(is_system_prefix) { READ_NEEDBUF(4); do_sysex(data_buffer + offset + 1, 1); if(data_buffer[offset + 1] == 0xf7) is_system_prefix = 0; /* End SysEX */ READ_ADVBUF(4); break; } READ_NEEDBUF(2); switch(data_buffer[offset + 1] & 0xf0) { case MIDI_NOTEON: READ_NEEDBUF(12); ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = data_buffer[offset + 9] & 0x7f; if(ev.b != 0) ev.type = ME_NOTEON; else ev.type = ME_NOTEOFF; seq_play_event(&ev); READ_ADVBUF(12); break; case MIDI_NOTEOFF: READ_NEEDBUF(12); ev.type = ME_NOTEOFF; ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = data_buffer[offset + 9] & 0x7f; seq_play_event(&ev); READ_ADVBUF(12); break; case MIDI_KEY_PRESSURE: READ_NEEDBUF(12); ev.type = ME_KEYPRESSURE; ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = data_buffer[offset + 9] & 0x7f; seq_play_event(&ev); READ_ADVBUF(12); break; case MIDI_CTL_CHANGE: READ_NEEDBUF(12); if(convert_midi_control_change(data_buffer[offset + 1] & 0x0f, data_buffer[offset + 5], data_buffer[offset + 9], &ev)) seq_play_event(&ev); READ_ADVBUF(12); break; case MIDI_PGM_CHANGE: READ_NEEDBUF(8); ev.type = ME_PROGRAM; ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = 0; seq_play_event(&ev); READ_ADVBUF(8); break; case MIDI_CHN_PRESSURE: READ_NEEDBUF(8); ev.type = ME_CHANNEL_PRESSURE; ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = 0; seq_play_event(&ev); READ_ADVBUF(8); break; case MIDI_PITCH_BEND: READ_NEEDBUF(12); ev.type = ME_PITCHWHEEL; ev.channel = data_buffer[offset + 1] & 0x0f; ev.a = data_buffer[offset + 5] & 0x7f; ev.b = data_buffer[offset + 9] & 0x7f; seq_play_event(&ev); READ_ADVBUF(12); break; case MIDI_SYSTEM_PREFIX: READ_NEEDBUF(4); do_sysex(data_buffer + offset + 1, 1); is_system_prefix = 1; /* Start SysEX */ READ_ADVBUF(4); break; default: ctl.cmsg(CMSG_ERROR, VERB_NORMAL, "Undefined SEQ_MIDIPUTC 0x%02x", data_buffer[offset + 1]); send_status(402, "Undefined SEQ_MIDIPUTC 0x%02x", data_buffer[offset + 1]); return 1; } break; case SEQ_FULLSIZE: /* WARNING: This data may be devided into some socket fragments. */ offset = data_buffer_len; ctl.cmsg(CMSG_WARNING, VERB_NORMAL, "SEQ_FULLSIZE is received. This command is not safety."); break; case SEQ_EXTENDED: READ_NEEDBUF(8); do_extended(data_buffer + offset); READ_ADVBUF(8); break; case EV_SEQ_LOCAL: case SEQ_PRIVATE: READ_NEEDBUF(8); /* Ignore */ READ_ADVBUF(8); break; default: ctl.cmsg(CMSG_ERROR, VERB_NORMAL, "Undefined data 0x%02x", data_buffer[offset - 1]); send_status(401, "Wrong data is recieved (seqcmd=0x%02x)", cmd); stop_playing(); return 1; }#undef READ_NEEDBUF#undef READ_ADVBUF } done: if(offset) { data_buffer_len -= offset; memmove(data_buffer, data_buffer + offset, data_buffer_len); } return 0;}static void do_chn_voice(uint8 *data){ int type, chn, note, parm; MidiEvent ev; type = data[2]; chn = data[3] % MAX_CHANNELS; note = data[4] & 0x7f; parm = data[5] & 0x7f; ev.channel = chn; ev.a = note; ev.b = parm; switch(type) { case MIDI_NOTEON: if(parm > 0) { ev.type = ME_NOTEON; seq_play_event(&ev); break; } /* FALLTHROUGH */ case MIDI_NOTEOFF: ev.type = ME_NOTEOFF; seq_play_event(&ev); break; case MIDI_KEY_PRESSURE: ev.type = ME_KEYPRESSURE; seq_play_event(&ev); break; }}static void do_chn_common(uint8 *data){ int type, chn, p1, p2, w14; MidiEvent ev; type = data[2]; chn = data[3] % MAX_CHANNELS; p1 = data[4] & 0x7f; p2 = data[5] & 0x7f; w14 = data2short(data + 6) & 0x3fff; if(type == 0xff) /* Meta event */ { /* This event is special event for timidity. (not OSS compatible) */ switch(data[3]) { case 0x2f: /* End of midi */ stop_playing(); tmr_reset(); break; case 0x7f: /* Sequencer-Specific Meta-Event */ switch(data[4]) { case 0x01: /* MIDI Reset */ ev.type = ME_RESET; ev.a = DEFAULT_SYSTEM_MODE; ev.b = 0; seq_play_event(&ev); break; case 0x02: { /* Used to sync. */ double target_time, queue_time, sleep_time; if(w14 == 0) { aq_flush(0); /* wait until playout */ send_status(301, "0 Sync OK"); break; } aq_soft_flush(); target_time = (double)w14 / curr_timebase; queue_time = (double)aq_filled() / play_mode->rate; sleep_time = queue_time - target_time; if(sleep_time > 0) { send_status(301, "%g Sync OK", sleep_time); usleep((unsigned long)(sleep_time * 1000000)); } else send_status(301, "0 Sync OK"); } break; } } return; } ev.channel = chn; switch(type) { case MIDI_CTL_CHANGE: if(convert_midi_control_change(chn, p1, w14, &ev)) seq_play_event(&ev); break; case MIDI_PGM_CHANGE: ev.type = ME_PROGRAM; ev.a = p1; ev.b = 0; seq_play_event(&ev); break; case MIDI_CHN_PRESSURE: ev.type = ME_CHANNEL_PRESSURE; ev.a = p1; ev.b = p2; seq_play_event(&ev); break; case MIDI_PITCH_BEND: ev.type = ME_PITCHWHEEL; ev.a = w14 & 0x7f; ev.b = (w14>>7) & 0x7f; seq_play_event(&ev); break; }}static void do_timing(uint8 *data){ int32 val; val = data2long(data + 4); switch(data[1]) { case TMR_START: tmr_running = 1; tmr_reset(); event_time_offset = (int32)(play_mode->rate * high_time_at); break; case TMR_STOP: tmr_running = 0; break; case TMR_CONTINUE: if(!tmr_running) { tmr_running = 1; tick_offs = curr_tick; start_time = get_current_calender_time(); } break; case TMR_TEMPO:#if 0 /* What should TMR_TEMPO work ? */ if(val < 8) val = 8; else if(val > 250) val = 250; current_play_tempo = 60 * 1000000 / val; compute_sample_increment();#endif break; case TMR_WAIT_ABS:/* printf("## TMR_WAIT_ABS: %d %d %d %g\n", curr_tick, curr_tick - (time2tick(get_current_calender_time() - start_time) + tick_offs), event_time_offset, (double)aq_filled() / play_mode->rate); */ val -= curr_tick; /*FALLTHROUGH*/ case TMR_WAIT_REL: if(val <= 0) break; add_tick(val); break;#if 0 case TMR_ECHO: case TMR_SPP:#endif default:/* printf("## TMR=0x%02x is not supported\n", data[1]); */ break; }}static void do_sysex(uint8 *data, int n){ static uint8 sysexbuf[BUFSIZ]; static int buflen; static int fillflag; int i; if(data == NULL) { buflen = fillflag = 0; is_system_prefix = 0; return; } for(i = 0; i < n; i++) { /* SysEx := /\xf0([^\xf7]*\xf7)/ */ if(!fillflag) { if(data[i] == 0xf0) { fillflag = 1; continue; } } if(fillflag) { if(buflen < sizeof(sysexbuf)) sysexbuf[buflen++] = data[i]; if(data[i] == 0xf7) { MidiEvent ev; if(parse_sysex_event(sysexbuf, buflen, &ev)) seq_play_event(&ev); buflen = 0; fillflag = 0; } } }}static void do_extended(uint8 *data){ int value; MidiEvent ev; value = data[5] | data[6] * 256; switch(data[1]) { case SEQ_CONTROLLER: switch(data[4]) { case CTRL_PITCH_BENDER: /* ?? */ break; case CTRL_PITCH_BENDER_RANGE: /* ?? */ ev.channel = data[3] % MAX_CHANNELS; ev.b = 0; ev.a = 0; /* LSB */ ev.type = ME_NRPN_LSB; seq_play_event(&ev); /* MSB */ ev.type = ME_NRPN_MSB; seq_play_event(&ev); /* Data entry */ ev.type = ME_DATA_ENTRY_MSB; ev.a = value / 100; /* ?? */ seq_play_event(&ev); break; default: break; } break; default: break; }}/* * interface_<id>_loader(); */ControlMode *interface_r_loader(void){ return &ctl;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -