long audriv_get_filled(void) /* オーディオバッファ内のバイト数を返します。 * エラーの場合は -1 を返します。 */ { long n; if(play_counter <= 0) return 0; n = (int)((double)play_sample_rate * play_sample_size * (get_current_calender_time() - play_start_time)); if(n > play_counter) return 0; return play_counter - n; }
static long calculate_play_samples(void) { long n, ret; if(play_counter <= 0) return 0; n = (long)((double)play_sample_rate * (double)play_sample_size * (get_current_calender_time() - play_start_time)); if(n > play_counter) ret = play_counter / play_sample_size; else ret = n / play_sample_size; return ret; }
static void CanvasUpdateInterval(void) { static double lasttime; double t; if (CanvasGetMode() == CANVAS_MODE_MAP16 || CanvasGetMode() == CANVAS_MODE_MAP32) { t = get_current_calender_time(); if (t - lasttime > 0.05) { CanvasReadPanelInfo(0); CanvasUpdate(0); CanvasPaint(); lasttime = t; } } else if (CanvasGetMode() == CANVAS_MODE_GSLCD) ctl_gslcd_update(); }
static void reset_indicator(void) { int i; memset(comment_indicator_buffer, ' ', indicator_width - 1); comment_indicator_buffer[indicator_width - 1] = '\0'; next_indicator_chan = -1; indicator_last_update = get_current_calender_time(); indicator_mode = INDICATOR_DEFAULT; indicator_msgptr = NULL; for(i = 0; i < MAX_CHANNELS; i++) { instr_comment[i].last_note_on = 0.0; instr_comment[i].comm = channel_instrum_name(i); } }
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); }
int audriv_write(char *buff, int n) /* audio に buff を n バイト分流し込みます. * audriv_set_noblock_write() で非ブロック・モードが設定された * 場合は,この関数の呼び出しは即座に処理が返ります. * 返り値は実際に流し込まれたバイト数であり,非ブロック・モードが設定 * されている場合は,引数 n より少ない場合があります. * 失敗すると -1 を返し,成功すると,実際に流し込まれたバイト数を返します. */ { long qsz; qsz = audriv_get_filled(); if(qsz == -1) return -1; if(qsz == 0) { reset_samples += play_counter / play_sample_size; play_counter = 0; /* Reset start time */ } if(play_counter == 0) play_start_time = get_current_calender_time(); play_counter += n; return n; }
static void display_lyric(char *lyric, int sep) { char *p; int len, idlen, sepoffset; static int crflag = 0; if(lyric == NULL) { indicator_last_update = get_current_calender_time(); crflag = 0; return; } if(indicator_mode != INDICATOR_LYRIC || crflag) { memset(comment_indicator_buffer, 0, indicator_width); SLsmg_gotorc(lyric_row,0); SLsmg_erase_eol(); ctl_refresh(); indicator_mode = INDICATOR_LYRIC; crflag = 0; } if(*lyric == '\0') { indicator_last_update = get_current_calender_time(); return; } else if(*lyric == '\n') { if(!ctl.trace_playing) { crflag = 1; lyric_row++; SLsmg_gotorc(0,lyric_row); return; } else lyric = " / "; } if(strchr(lyric, '\r') != NULL) { crflag = 1; if(!ctl.trace_playing) { int i; for(i = title_row+1; i <= lyric_row; i++) { SLsmg_gotorc(i,0); SLsmg_erase_eol(); } lyric_row = title_row+1; } if(lyric[0] == '\r' && lyric[1] == '\0') { indicator_last_update = get_current_calender_time(); return; } } idlen = strlen(comment_indicator_buffer); len = strlen(lyric); if(sep) { while(idlen > 0 && comment_indicator_buffer[idlen - 1] == ' ') comment_indicator_buffer[--idlen] = '\0'; while(len > 0 && lyric[len - 1] == ' ') len--; } if(len == 0) { /* update time stamp */ indicator_last_update = get_current_calender_time(); reuse_mblock(&tmpbuffer); return; } sepoffset = (sep != 0); if(len >= indicator_width - 2) { memcpy(comment_indicator_buffer, lyric, indicator_width - 1); comment_indicator_buffer[indicator_width - 1] = '\0'; } else if(idlen == 0) { memcpy(comment_indicator_buffer, lyric, len); comment_indicator_buffer[len] = '\0'; } else if(len + idlen + 2 < indicator_width) { if(sep) comment_indicator_buffer[idlen] = sep; memcpy(comment_indicator_buffer + idlen + sepoffset, lyric, len); comment_indicator_buffer[idlen + sepoffset + len] = '\0'; } else { int spaces; p = comment_indicator_buffer; spaces = indicator_width - idlen - 2; while(spaces < len) { char *q; /* skip one word */ if((q = strchr(p, ' ')) == NULL) { p = NULL; break; } do q++; while(*q == ' '); spaces += (q - p); p = q; } if(p == NULL) { SLsmg_gotorc(lyric_row,0); SLsmg_erase_eol(); memcpy(comment_indicator_buffer, lyric, len); comment_indicator_buffer[len] = '\0'; } else { int d, l, r, i, j; d = (p - comment_indicator_buffer); l = strlen(p); r = len - (indicator_width - 2 - l - d); j = d - r; for(i = 0; i < j; i++) comment_indicator_buffer[i] = ' '; for(i = 0; i < l; i++) comment_indicator_buffer[j + i] = comment_indicator_buffer[d + i]; if(sep) comment_indicator_buffer[j + i] = sep; memcpy(comment_indicator_buffer + j + i + sepoffset, lyric, len); comment_indicator_buffer[j + i + sepoffset + len] = '\0'; } } SLsmg_printfrc(lyric_row,0,"%s",comment_indicator_buffer); ctl_refresh(); reuse_mblock(&tmpbuffer); indicator_last_update = get_current_calender_time(); }
static void update_indicator(void) { double t; int i; char c; t = get_current_calender_time(); if(indicator_mode != INDICATOR_DEFAULT) { int save_chan; if(indicator_last_update + SCRMODE_OUT_THRESHOLD > t) return; save_chan = next_indicator_chan; reset_indicator(); next_indicator_chan = save_chan; } else { if(indicator_last_update + INDICATOR_UPDATE_TIME > t) return; } indicator_last_update = t; if(indicator_msgptr != NULL && *indicator_msgptr == '\0') indicator_msgptr = NULL; if(indicator_msgptr == NULL) { if(next_indicator_chan >= 0 && instr_comment[next_indicator_chan].comm != NULL && *instr_comment[next_indicator_chan].comm) { current_indicator_chan = next_indicator_chan; } else { int prog; prog = instr_comment[current_indicator_chan].prog; for(i = 0; i < MAX_CHANNELS; i++) { current_indicator_chan++; if(current_indicator_chan == MAX_CHANNELS) current_indicator_chan = 0; if(instr_comment[current_indicator_chan].comm != NULL && *instr_comment[current_indicator_chan].comm && instr_comment[current_indicator_chan].prog != prog && (instr_comment[current_indicator_chan].last_note_on + CHECK_NOTE_SLEEP_TIME > t || instr_comment[current_indicator_chan].disp_cnt == 0)) break; } if(i == MAX_CHANNELS) return; } next_indicator_chan = -1; if(instr_comment[current_indicator_chan].comm == NULL || *instr_comment[current_indicator_chan].comm == '\0') return; snprintf(current_indicator_message, indicator_width, "%03d:%s ", instr_comment[current_indicator_chan].prog, instr_comment[current_indicator_chan].comm); instr_comment[current_indicator_chan].disp_cnt++; indicator_msgptr = current_indicator_message; } c = *indicator_msgptr++; for(i = 0; i < indicator_width - 2; i++) comment_indicator_buffer[i] = comment_indicator_buffer[i + 1]; comment_indicator_buffer[indicator_width - 2] = c; SLsmg_printfrc(2,0,comment_indicator_buffer); ctl_refresh(); }
int aq_flush(int discard) { int rc; int more_trace; /* to avoid infinite loop */ double t, timeout_expect; aq_add_count = 0; init_effect(); if(discard) { trace_flush(); if(play_mode->acntl(PM_REQ_DISCARD, NULL) != -1) { flush_buckets(); return RC_NONE; } ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "ERROR: Can't discard audio buffer"); } if(!IS_STREAM_TRACE) { play_mode->acntl(PM_REQ_FLUSH, NULL); play_counter = play_offset_counter = 0; return RC_NONE; } rc = aq_soft_flush(); if(RC_IS_SKIP_FILE(rc)) return rc; more_trace = 1; t = get_current_calender_time(); timeout_expect = t + (double)aq_filled() / play_mode->rate; while(more_trace || aq_filled() > 0) { rc = check_apply_control(); if(RC_IS_SKIP_FILE(rc)) { play_mode->acntl(PM_REQ_DISCARD, NULL); flush_buckets(); return rc; } more_trace = trace_loop(); t = get_current_calender_time(); if(t >= timeout_expect - 0.1) break; if(!more_trace) usleep((unsigned long)((timeout_expect - t) * 1000000)); else aq_wait_ticks(); } trace_flush(); play_mode->acntl(PM_REQ_FLUSH, NULL); flush_buckets(); return RC_NONE; }
/* Estimates the size of audio device queue. * About sun audio, there are long-waiting if buffer of device audio is full. * So it is impossible to completely estimate the size. */ static int32 estimate_queue_size(void) { char *nullsound; double tb, init_time, chunktime; int32 qbytes, max_qbytes; int ntries; nullsound = (char *)safe_malloc(bucket_size); memset(nullsound, 0, bucket_size); if(play_mode->encoding & (PE_ULAW|PE_ALAW)) general_output_convert((int32 *)nullsound, bucket_size/Bps); tb = play_mode->rate * Bps * TEST_SPARE_RATE; ntries = 1; max_qbytes = play_mode->rate * MAX_FILLED_TIME * Bps; retry: chunktime = (double)bucket_size / Bps / play_mode->rate; qbytes = 0; init_time = get_current_calender_time(); /* Start */ for(;;) { double start, diff; start = get_current_calender_time(); if(start - init_time > 1.0) /* ?? */ { ctl->cmsg(CMSG_WARNING, VERB_DEBUG, "Warning: Audio test is terminated"); break; } play_mode->output_data(nullsound, bucket_size); diff = get_current_calender_time() - start; if(diff > chunktime/2 || qbytes > 1024*512 || chunktime < diff) break; qbytes += (int32)((chunktime - diff) * tb); if(qbytes > max_qbytes) { qbytes = max_qbytes; break; } } play_mode->acntl(PM_REQ_DISCARD, NULL); if(bucket_size * 2 > qbytes) { if(ntries == 4) { ctl->cmsg(CMSG_ERROR, VERB_NOISY, "Can't estimate audio queue length"); bucket_size = audio_buffer_size * Bps; free(nullsound); return 2 * audio_buffer_size * Bps; } ctl->cmsg(CMSG_WARNING, VERB_DEBUG, "Retry to estimate audio queue length (%d times)", ntries); bucket_size /= 2; ntries++; goto retry; } free(nullsound); return qbytes; }
static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]) { static int init_flag = 1; int rc; int32 value; extern void timidity_init_aq_buff(void); int errcnt; w32g_add_playlist(number_of_files, list_of_files, 0, ctl.flags & CTLF_AUTOUNIQ, ctl.flags & CTLF_AUTOREFINE); w32g_play_active = 0; errcnt = 0; if(init_flag && w32g_nvalid_playlist() && (ctl.flags & CTLF_AUTOSTART)) // if(play_mode->fd != -1 && // w32g_nvalid_playlist() && (ctl.flags & CTLF_AUTOSTART)) rc = RC_LOAD_FILE; else rc = RC_NONE; init_flag = 0; #ifdef W32G_RANDOM_IS_SHUFFLE w32g_shuffle_playlist_reset(0); #endif while(1) { if(rc == RC_NONE) { if(play_mode->fd != -1) { aq_flush(1); play_mode->close_output(); } rc = w32g_get_rc(&value, 1); } redo: switch(rc) { case RC_NONE: Sleep(1000); break; case RC_LOAD_FILE: /* Play playlist.selected */ if(w32g_nvalid_playlist()) { int selected; w32g_get_playlist_index(&selected, NULL, NULL); w32g_play_active = 1; if(play_mode->fd == -1) { if(play_mode->open_output() == -1) { ctl.cmsg(CMSG_FATAL, VERB_NORMAL, "Couldn't open %s (`%c') %s", play_mode->id_name, play_mode->id_character, play_mode->name ? play_mode->name : ""); break; } aq_setup(); timidity_init_aq_buff(); } if(play_mode->id_character == 'l') w32g_show_console(); if(!DocWndIndependent) { w32g_setup_doc(selected); if(DocWndAutoPopup) w32g_open_doc(1); else w32g_open_doc(2); } { char *p = w32g_get_playlist(selected); if(Panel!=NULL && p!=NULL) strcpy(Panel->filename,p); } SetWrdWndActive(); rc = play_midi_file(w32g_get_playlist(selected)); if(ctl.flags & CTLF_NOT_CONTINUE) w32g_update_playlist(); /* Update mark of error */ if(rc == RC_ERROR) { int nfiles; errcnt++; w32g_get_playlist_index(NULL, &nfiles, NULL); if(errcnt >= nfiles) w32g_msg_box("No MIDI file to play", "TiMidity Warning", MB_OK); } else errcnt = 0; w32g_play_active = 0; goto redo; } break; case RC_ERROR: case RC_TUNE_END: #if 0 if(play_mode->id_character != 'd' || (ctl.flags & CTLF_NOT_CONTINUE)) { #else if(ctl.flags & CTLF_NOT_CONTINUE) { #endif break; } /* FALLTHROUGH */ case RC_NEXT: if(!w32g_nvalid_playlist()) { if(ctl.flags & CTLF_AUTOEXIT) { if(play_mode->fd != -1) aq_flush(0); return; } break; } if(ctl.flags & CTLF_LIST_RANDOM) { #ifdef W32G_RANDOM_IS_SHUFFLE if(w32g_shuffle_playlist_next(!(ctl.flags & CTLF_NOT_CONTINUE))) { #else if(w32g_random_playlist(!(ctl.flags & CTLF_NOT_CONTINUE))) { #endif rc = RC_LOAD_FILE; goto redo; } } else { if(w32g_next_playlist(!(ctl.flags & CTLF_NOT_CONTINUE))) { rc = RC_LOAD_FILE; goto redo; } } { /* end of list */ if(ctl.flags & CTLF_AUTOEXIT) { if(play_mode->fd != -1) aq_flush(0); return; } if((ctl.flags & CTLF_LIST_LOOP) && w32g_nvalid_playlist()) { #ifdef W32G_RANDOM_IS_SHUFFLE if(ctl.flags & CTLF_LIST_RANDOM) { w32g_shuffle_playlist_reset(0); w32g_shuffle_playlist_next(!(ctl.flags & CTLF_NOT_CONTINUE)); } else { #endif w32g_first_playlist(!(ctl.flags & CTLF_NOT_CONTINUE)); #ifdef W32G_RANDOM_IS_SHUFFLE } #endif rc = RC_LOAD_FILE; goto redo; } if((ctl.flags & CTLF_LIST_RANDOM) && w32g_nvalid_playlist()) w32g_shuffle_playlist_reset(0); } break; case RC_REALLY_PREVIOUS: #ifdef W32G_RANDOM_IS_SHUFFLE w32g_shuffle_playlist_reset(0); #endif if(w32g_prev_playlist(!(ctl.flags & CTLF_NOT_CONTINUE))) { rc = RC_LOAD_FILE; goto redo; } break; case RC_QUIT: if(play_mode->fd != -1) aq_flush(1); return; case RC_CHANGE_VOLUME: amplification += value; ctl_master_volume(amplification); break; case RC_TOGGLE_PAUSE: play_pause_flag = !play_pause_flag; break; default: if(rc == RC_STOP) #ifdef W32G_RANDOM_IS_SHUFFLE w32g_shuffle_playlist_reset(0); #endif if(rc >= RC_EXT_BASE) { rc = w32g_ext_control(rc, value); if(rc != RC_NONE) goto redo; } break; } if(mark_apply_setting) PrefSettingApplyReally(); rc = RC_NONE; } } static void ctl_lcd_mark(int flag, int x, int y) { Panel->GSLCD[x][y] = flag; } static void ctl_gslcd(int id) { char *lcd; int i, j, k, data, mask; char tmp[3]; if((lcd = event2string(id)) == NULL) return; if(lcd[0] != ME_GSLCD) return; lcd++; for(i = 0; i < 16; i++) { for(j = 0; j < 4; j++) { tmp[0]= lcd[2 * (j * 16 + i)]; tmp[1]= lcd[2 * (j * 16 + i) + 1]; if(sscanf(tmp, "%02X", &data) != 1) { /* Invalid format */ return; } mask = 0x10; for(k = 0; k < 5; k++) { if(data & mask) { ctl_lcd_mark(1, j * 5 + k, i); } else { ctl_lcd_mark(0, j * 5 + k, i); } mask >>= 1; } } } Panel->gslcd_displayed_flag = 1; Panel->gslcd_last_display_time = get_current_calender_time(); Panel->changed = 1; } static void ctl_channel_note(int ch, int note, int vel) { if (vel == 0) { if (note == Panel->cnote[ch]) Panel->v_flags[ch] = FLAG_NOTE_OFF; Panel->cvel[ch] = 0; } else if (vel > Panel->cvel[ch]) { Panel->cvel[ch] = vel; Panel->cnote[ch] = note; Panel->ctotal[ch] = ( vel * Panel->channel[ch].volume * Panel->channel[ch].expression ) >> 14; // Panel->channel[ch].expression / (127*127); Panel->v_flags[ch] = FLAG_NOTE_ON; } Panel->changed = 1; }
int rtsyn_np_play_some_data(void) { UINT wMsg; DWORD dwParam1; DWORD dwParam2; MidiEvent ev; MidiEvent evm[260]; UINT evbpoint; MIDIHDR *IIMidiHdr; int exlen; char *sysexbuffer; int ne,i,j,chk,played; UINT port; static DWORD pre_time; static DWORD timeoffset; double event_time; // rtsyn_play_one_data (0,0x007f3c90, get_current_calender_time()); if ( 0 != read_pipe_data()) return 0; played=0; if( -1 == rtsyn_np_buf_check() ){ played=~0; return played; } do{ EnterCriticalSection(&mim_np_section); evbpoint=np_evbrpoint; if (++np_evbrpoint >= EVBUFF_SIZE) np_evbrpoint -= EVBUFF_SIZE; wMsg=evbuf[evbpoint].wMsg; port=evbuf[evbpoint].port; dwParam1=evbuf[evbpoint].dwParam1; dwParam2=evbuf[evbpoint].dwParam2; exlen = evbuf[evbpoint].exlen; sysexbuffer = evbuf[evbpoint].exbuffer; LeaveCriticalSection(&mim_np_section); if(rtsyn_sample_time_mode !=1){ if((first_ev == 1) || ( pre_time > dwParam2)){ pre_time=dwParam2; timeoffset=dwParam2; mim_start_time = get_current_calender_time(); first_ev=0; } if(dwParam2 !=0){ event_time= mim_start_time+((double)(dwParam2-timeoffset))*(double)1.0/(double)1000.0; }else{ event_time = get_current_calender_time(); } } switch (wMsg) { case RTSYN_NP_DATA: if(rtsyn_sample_time_mode !=1){ rtsyn_play_one_data(port, dwParam1, event_time); }else{ rtsyn_play_one_data(port, dwParam1, dwParam2); } break; case RTSYN_NP_LONGDATA: if(rtsyn_sample_time_mode !=1){ rtsyn_play_one_sysex(sysexbuffer,exlen, event_time); }else{ rtsyn_play_one_sysex(sysexbuffer,exlen, dwParam2); } free(sysexbuffer); break; } pre_time =dwParam2; }while( 0==rtsyn_np_buf_check()); return played; }