// avoid adapter close unless all the adapters can be closed int adapter_timeout(sockets *s) { int do_close = 1, i, max_close = 0; int rtime = getTick(); adapter *ad = get_adapter(s->sid); if (!ad) return 1; if (ad->force_close) return 1; if (get_streams_for_adapter(ad->id) > 0) { ad->rtime = getTick(); s->rtime = ad->rtime; LOG("Keeping the adapter %d open as there are active streams", ad->id); return 0; } for (i = 0; i < MAX_ADAPTERS; i++) if ((ad = get_adapter_nw(i))) { if (rtime - ad->rtime < s->close_sec) do_close = 0; if (ad && max_close < ad->rtime) max_close = ad->rtime; } LOG("Requested adapter %d close due to timeout, result %d max_rtime %d", s->sid, do_close, max_close); if (!do_close) s->rtime = max_close; return do_close; }
unsigned char *getItem(int64_t key) { STmpinfo *s = getItemPos(key); if (s) s->last_updated = getTick(); return s ? s->data : NULL; }
int tune(int aid, int sid) { adapter *ad = get_adapter(aid); int rv = 0; SPid *p; if (!ad) return -400; mutex_lock(&ad->mutex); ad->last_sort = getTick(); if (sid == ad->master_sid && ad->do_tune) { ad->tp.switch_type = ad->switch_type; ad->tp.uslot = ad->uslot; ad->tp.ufreq = ad->ufreq; ad->tp.pin = ad->pin; ad->tp.committed_no = ad->committed_no; ad->tp.uncommitted_no = ad->uncommitted_no; rv = ad->tune(ad->id, &ad->tp); ad->status = 0; ad->status_cnt = 0; set_socket_pos(ad->sock, 0); // flush the existing buffer ad->rlen = 0; if (ad->sid_cnt > 1) // the master changed the frequency { close_streams_for_adapter(aid, sid); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } } #ifdef TABLES_H p = find_pid(aid, 0); if (!p || p->flags == 3) // add pid 0 if not explicitly added { LOG( "Adding pid 0 to the list of pids as not explicitly added for adapter %d", aid); mark_pid_add(-1, aid, 0); } #endif } else LOG("not tuning for SID %d (do_tune=%d, master_sid=%d)", sid, ad->do_tune, ad->master_sid); if (rv < 0) mark_pids_deleted(aid, sid, NULL); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } mutex_unlock(&ad->mutex); return rv; }
/// \details /// Return elapsed time (in seconds) since last call with this handle /// and clear for next lap. double getElapsedTime(const enum TimerHandle handle) { double etime = getTick() * (double)perfTimer[handle].elapsed; perfTimer[handle].elapsed = 0; return etime; }
void smeTIME_Update() { const fix32 current = getTick()<<7; const fix32 delta = current-sme_Last; sme_Last = current; sme_DeltaTime = delta; }
void Thread::sleep(unsigned int ms) { if(ms==0) return; //pauseKernel() here is not enough since even if the kernel is stopped //the tick isr will wake threads, modifying the sleeping_list { FastInterruptDisableLock lock; SleepData d; d.p=const_cast<Thread*>(cur); if(((ms*TICK_FREQ)/1000)>0) d.wakeup_time=getTick()+(ms*TICK_FREQ)/1000; //If tick resolution is too low, wait one tick else d.wakeup_time=getTick()+1; IRQaddToSleepingList(&d);//Also sets SLEEP_FLAG } Thread::yield(); }
/// \details /// The report contains two blocks. The upper block is performance /// information for the printRank. The lower block is statistical /// information over all ranks. void printPerformanceResults(int nGlobalAtoms, int printRate) { // Collect timer statistics overall and across ranks timerStats(); if (!printRank()) return; // only print timers with non-zero values. double tick = getTick(); double loopTime = perfTimer[loopTimer].total*tick; fprintf(screenOut, "\n\nTimings for Rank %d\n", getMyRank()); fprintf(screenOut, " Timer # Calls Avg/Call (s) Total (s) %% Loop\n"); fprintf(screenOut, "___________________________________________________________________\n"); /* for (int ii=0; ii<numberOfTimers; ++ii) { double totalTime = perfTimer[ii].total*tick; if (perfTimer[ii].count > 0) fprintf(screenOut, "%-16s%12"PRIu64" %8.4f %8.4f %8.2f\n", timerName[ii], perfTimer[ii].count, totalTime/(double)perfTimer[ii].count, totalTime, totalTime/loopTime*100.0); }*/ fprintf(screenOut, "\nTiming Statistics Across %d Ranks:\n", getNRanks()); fprintf(screenOut, " Timer Rank: Min(s) Rank: Max(s) Avg(s) Stdev(s)\n"); fprintf(screenOut, "_____________________________________________________________________________\n"); /* for (int ii = 0; ii < numberOfTimers; ++ii) { if (perfTimer[ii].count > 0) fprintf(screenOut, "%-16s%6d:%10.4f %6d:%10.4f %10.4f %10.4f\n", timerName[ii], perfTimer[ii].minRank, perfTimer[ii].minValue*tick, perfTimer[ii].maxRank, perfTimer[ii].maxValue*tick, perfTimer[ii].average*tick, perfTimer[ii].stdev*tick); }*/ double atomsPerTask = nGlobalAtoms/(real_t)getNRanks(); perfGlobal.atomRate = perfTimer[timestepTimer].average * tick * 1e6 / (atomsPerTask * perfTimer[timestepTimer].count * printRate); perfGlobal.atomAllRate = perfTimer[timestepTimer].average * tick * 1e6 / (nGlobalAtoms * perfTimer[timestepTimer].count * printRate); perfGlobal.atomsPerUSec = 1.0 / perfGlobal.atomAllRate; fprintf(screenOut, "\n---------------------------------------------------\n"); // fprintf(screenOut, " Average atom update rate: %6.2f us/atom/task\n", perfGlobal.atomRate); fprintf(screenOut, "---------------------------------------------------\n\n"); fprintf(screenOut, "\n---------------------------------------------------\n"); // fprintf(screenOut, " Average all atom update rate: %6.2f us/atom\n", perfGlobal.atomAllRate); fprintf(screenOut, "---------------------------------------------------\n\n"); fprintf(screenOut, "\n---------------------------------------------------\n"); // fprintf(screenOut, " Average atom rate: %6.2f atoms/us\n", perfGlobal.atomsPerUSec); fprintf(screenOut, "---------------------------------------------------\n\n"); }
int satipc_open_device(adapter *ad) { if (!ad->sip) return 1; int ctime = getTick(); if ((ad->last_connect > 0) && (ctime - ad->last_connect < 30000)) return 3; ad->last_connect = ctime; ad->fe = tcp_connect(ad->sip, ad->sport, NULL, 0); // non-blockin socket if (ad->fe < 0) return 2; LOG("satipc: connected to SAT>IP server %s port %d, handle %d", ad->sip, ad->sport, ad->fe); ad->listen_rtp = opts.start_rtp + 1000 + ad->id * 2; ad->dvr = udp_bind(NULL, ad->listen_rtp); ad->rtcp = udp_bind(NULL, ad->listen_rtp + 1); ad->fe_sock = sockets_add(ad->fe, NULL, ad->id, TYPE_TCP, (socket_action) satipc_reply, (socket_action) satipc_close, (socket_action) satipc_timeout); ad->rtcp_sock = sockets_add(ad->rtcp, NULL, ad->id, TYPE_TCP, (socket_action) satipc_rtcp_reply, (socket_action) satipc_close, NULL); sockets_timeout(ad->fe_sock, 15000); // 15s set_socket_receive_buffer(ad->dvr, opts.output_buffer); if (ad->fe_sock < 0 || ad->dvr < 0 || ad->rtcp < 0 || ad->rtcp_sock < 0) { sockets_del(ad->rtcp_sock); sockets_del(ad->fe_sock); close(ad->rtcp); close(ad->dvr); close(ad->fe); } ad->type = ADAPTER_SATIP; ad->session[0] = 0; lap[ad->id] = 0; ldp[ad->id] = 0; ad->cseq = 1; ad->err = 0; ad->expect_reply = 0; ad->last_connect = 0; ad->sent_transport = 0; ad->session[0] = 0; ad->stream_id = -1; ad->wp = ad->qp = ad->want_commit = 0; ad->rcvp = ad->repno = 0; ad->rtp_miss = ad->rtp_ooo = 0; ad->rtp_seq = 0xFFFF; ad->ignore_packets = 1; ad->force_commit = 0; ad->satip_last_setup = -10000; ad->last_cmd = 0; return 0; }
int TimerManager::run() { int nextMin = 0; uint64_t x = getTick(); uint64_t nextTick = x + 1000; while(!s.wait(nextTick > x ? nextTick - x : 0)) { uint32_t z = getTick(); nextTick = z + 1000; fire(TimerManagerListener::Second(), z); if(nextMin++ >= 60) { fire(TimerManagerListener::Minute(), z); nextMin = 0; } x = getTick(); } return 0; }
void Timer::getFPS() { fps_time += getTick(); fps++; if(fps_time < 1000000) return; printf("FPS: %.1f\n", (float)((float)fps / ((float)(fps_time) / 1000000.0))); fps = 0; fps_time = 0; }
void Timer::limitFPS(int fps) { int t = (1.0 / (float)fps) * 1000000; if(t < getTick()) return; //sf::sleep((t - getTick()) / 1000); //SDL_Delay((t - getTick()) / 1000); endTime(); }
int sockets_add(int sock, struct sockaddr_in *sa, int sid, int type, socket_action a, socket_action c, socket_action t) { int i; char ra[50]; if (init_sock == 0) { init_sock = 1; for (i = 0; i < MAX_SOCKS; i++) s[i].sock = -1; } for (i = 0; i < MAX_SOCKS; i++) if (s[i].sock < 0) break; if (i == MAX_SOCKS) return -1; s[i].sock = sock; memset(&s[i].sa, 0, sizeof(s[i].sa)); if (sa) memcpy(&s[i].sa, sa, sizeof(s[i].sa)); s[i].action = s[i].close = s[i].timeout = NULL; if (a) s[i].action = a; if (c) s[i].close = c; if (t) s[i].timeout = t; s[i].sid = sid; s[i].type = type & ~TYPE_CONNECT; s[i].rtime = getTick(); s[i].wtime = 0; if (max_sock <= i) max_sock = i + 1; s[i].buf = NULL; s[i].lbuf = 0; s[i].close_sec = 0; s[i].id = i; s[i].read = (read_action) sockets_read; if (s[i].type == TYPE_UDP || s[i].type == TYPE_RTCP) s[i].read = (read_action) sockets_recv; else if (s[i].type == TYPE_SERVER) s[i].read = (read_action) sockets_accept; pf[i].fd = sock; pf[i].events = POLLIN | POLLPRI; if (type & TYPE_CONNECT) pf[i].events |= POLLOUT; pf[i].revents = 0; LOG( "sockets_add: handle %d (type %d) returning socket index %d [%s:%d] read: %p", s[i].sock, s[i].type, i, get_socket_rhost(i, ra, sizeof(ra)), ntohs(s[i].sa.sin_port), s[i].read); return i; }
void printPerformanceResultsYaml(FILE* file) { if (! printRank()) return; double tick = getTick(); double loopTime = perfTimer[loopTimer].total*tick; fprintf(file,"\nPerformance Results:\n"); fprintf(file, " TotalRanks: %d\n", getNRanks()); fprintf(file, " ReportingTimeUnits: seconds\n"); fprintf(file, "Performance Results For Rank %d:\n", getMyRank()); for (int ii = 0; ii < numberOfTimers; ii++) { if (perfTimer[ii].count > 0) { double totalTime = perfTimer[ii].total*tick; fprintf(file, " Timer: %s\n", timerName[ii]); fprintf(file, " CallCount: %"PRIu64"\n", perfTimer[ii].count); fprintf(file, " AvgPerCall: %8.4f\n", totalTime/(double)perfTimer[ii].count); fprintf(file, " Total: %8.4f\n", totalTime); fprintf(file, " PercentLoop: %8.2f\n", totalTime/loopTime*100); } } fprintf(file, "Performance Results Across Ranks:\n"); for (int ii = 0; ii < numberOfTimers; ii++) { if (perfTimer[ii].count > 0) { fprintf(file, " Timer: %s\n", timerName[ii]); fprintf(file, " MinRank: %d\n", perfTimer[ii].minRank); fprintf(file, " MinTime: %8.4f\n", perfTimer[ii].minValue*tick); fprintf(file, " MaxRank: %d\n", perfTimer[ii].maxRank); fprintf(file, " MaxTime: %8.4f\n", perfTimer[ii].maxValue*tick); fprintf(file, " AvgTime: %8.4f\n", perfTimer[ii].average*tick); fprintf(file, " StdevTime: %8.4f\n", perfTimer[ii].stdev*tick); } } fprintf(file,"Performance Global Update Rates:\n"); fprintf(file, " AtomUpdateRate:\n"); fprintf(file, " AverageRate: %6.2f\n", perfGlobal.atomRate); fprintf(file, " Units: us/atom/task\n"); fprintf(file, " AllAtomUpdateRate:\n"); fprintf(file, " AverageRate: %6.2f\n", perfGlobal.atomAllRate); fprintf(file, " Units: us/atom\n"); fprintf(file, " AtomRate:\n"); fprintf(file, " AverageRate: %6.2f\n", perfGlobal.atomsPerUSec); fprintf(file, " Units: atoms/us\n"); fprintf(file, "\n"); }
int sockets_add(int sock, struct sockaddr_in *sa, int sid, int type, socket_action a, socket_action c, socket_action t) { int i; char ra[50]; sockets *ss; i = add_new_lock((void **) s, MAX_SOCKS, sizeof(sockets), &s_mutex); if (i == -1) LOG_AND_RETURN(-1, "sockets_add failed for socks %d", sock); ss = s[i]; ss->enabled = 1; ss->sock = sock; ss->tid = get_tid(); memset(&ss->sa, 0, sizeof(ss->sa)); if (sa) memcpy(&ss->sa, sa, sizeof(ss->sa)); ss->action = ss->close = ss->timeout = NULL; if (a) ss->action = a; if (c) ss->close = c; if (t) ss->timeout = t; ss->sid = sid; ss->type = type & ~TYPE_CONNECT; ss->rtime = getTick(); ss->wtime = 0; if (max_sock <= i) max_sock = i + 1; ss->buf = NULL; ss->lbuf = 0; ss->timeout_ms = 0; ss->id = i; ss->read = (read_action) sockets_read; ss->lock = NULL; if (ss->type == TYPE_UDP || ss->type == TYPE_RTCP) ss->read = (read_action) sockets_recv; else if (ss->type == TYPE_SERVER) ss->read = (read_action) sockets_accept; ss->events = POLLIN | POLLPRI; if (type & TYPE_CONNECT) ss->events |= POLLOUT; LOG( "sockets_add: handle %d (type %d) returning socket index %d [%s:%d] read: %p", ss->sock, ss->type, i, get_socket_rhost(i, ra, sizeof(ra)), ntohs(ss->sa.sin_port), ss->read); mutex_unlock(&ss->mutex); return i; }
int satipc_timeout(sockets *s) { adapter *ad = get_adapter(s->sid); LOG( "satipc: Sent keep-alive to the satip server %s:%d, adapter %d, socket_id %d, handle %d, timeout %d", ad?ad->sip:NULL, ad ? ad->sport : 0, s->sid, s->id, s->sock, s->close_sec); if (!ad) return 1; http_request(ad, NULL, "OPTIONS"); s->rtime = getTick(); return 0; }
void Thread::sleepUntil(long long absoluteTime) { //pauseKernel() here is not enough since even if the kernel is stopped //the tick isr will wake threads, modifying the sleeping_list { FastInterruptDisableLock lock; if(absoluteTime<=getTick()) return; //Wakeup time in the past, return SleepData d; d.p=const_cast<Thread*>(cur); d.wakeup_time=absoluteTime; IRQaddToSleepingList(&d);//Also sets SLEEP_FLAG } Thread::yield(); }
char * get_current_timestamp_log(void) { static char date_str[200]; time_t date; struct tm *t; time(&date); t = localtime(&date); if (!t) return "01/01 00:00:20"; snprintf(date_str, sizeof(date_str), "%02d/%02d %02d:%02d:%02d.%03d", t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, t->tm_sec, getTick()); return date_str; }
void Mediator::handleDispatcher(int index){ int fd = socketManager->getConnectedFD(index); char messageIN[BUFFER_SIZE]; int rd = ioStream->readLine(fd, messageIN, BUFFER_SIZE); if (rd > 0){ cout << "[From Dispatcher...]\t" << messageIN << flush; vector<char*> tokens ; char* token = strtok(messageIN, "|"); while (token != NULL){ tokens.push_back(token); token = strtok(NULL, "|\n"); } if (strcmp(tokens[0],"setupEnv") == 0) setupEnv(tokens, fd); else if (strcmp(tokens[0], "disconnect")==0){ disconnect(tokens[1], fd); } else if (strcmp(tokens[0], "BG_putFile")==0){ BG_put_file(tokens[1], atol(tokens[2]), fd); } else if (strcmp(tokens[0], "BG_start") == 0){ BG_start(tokens[1], atol(tokens[2])); } else if (strcmp(tokens[0], "JOB_STOP") ==0 ){ // processList.stopAll(); // becomeFree(); stopSimulation("dispatcher"); becomeFree(); simulationFinished(); } else if (strcmp(tokens[0], "JOB_ABORT") ==0 ){ abortSimulation(); } else if (strcmp(tokens[0], "getTick\n") == 0){ getTick(fd); } else cout << "else?" << endl << flush; } else{ socketManager->closeByIndex(index); cout << "Dispatcher Closed" << endl << flush; } }
STmpinfo *getFreeItemPos(int64_t key) { int i; int tick = getTick(); for (i = 0; i < MAX_SINFO; i++) if (!sinfo[i].enabled || (sinfo[i].timeout && (tick - sinfo[i].last_updated > sinfo[i].timeout))) { sinfo[i].id = i; sinfo[i].timeout = 0; sinfo[i].no_change = 0; sinfo[i].prev_no_change = 0; LOGL(2, "Requested new Item for key %llX, returning %d", key, i); return sinfo + i; } return NULL; }
void Game::run() { long frame = getTick(); int graphicframes = 0; int second = getTick() / TICKS_PER_SECOND; while (mState != EXIT) { logic(); if (getTick() - frame > 20) { frame = getTick(); std::cout << "Logic frame drop! =(" << std::endl; } frame++; if (frame > getTick()) { draw(); stretch_blit(mBuffer, screen, 0, 0, 320, 240, 0, 0, 640, 480); graphicframes++; } while (frame > getTick()) { rest(1); } if (second != getTick() / TICKS_PER_SECOND) { std::cout << "FPS: " << graphicframes << std::endl; std::cout << "State: " << mState << std::endl; second = getTick() / TICKS_PER_SECOND; graphicframes = 0; } } }
void MidiInfo::get3ByteInfo() { unsigned char actmsg; unsigned char* info; if(mode!=1){ info=new unsigned char[3]; actmsg=info[0]=by[cur++]; info[1]=by[cur++]; info[2]=by[cur++]; if(mode==0)il[curTick].add(info); if(mode==2)ir->getInfo(curTick,info); } else cur+=3; int steps,exit=0,tickAux; while(exit==0){ tickAux=curTick; steps=getTick(); if(by[cur]<0x80){ if(mode!=1){ info=new unsigned char[3]; info[0]=actmsg; info[1]=by[cur++]; info[2]=by[cur++]; if(mode==0)il[curTick].add(info); if(mode==2)ir->getInfo(curTick,info); } else cur+=2; }else{ curTick=tickAux; cur=cur-(steps); exit=1; } } }
int setItem(int64_t key, unsigned char *data, int len, int pos) // pos = -1 -> append, owerwrite the existing key { int new_key = 0; STmpinfo *s = getItemPos(key); if (!s) { s = getFreeItemPos(key); new_key = 1; } if (!s) return -1; if (s->max_size == 0) s->max_size = MAX_DATA + 10; if (!s->data) s->data = malloc1(s->max_size); if (!s->data) return -1; s->enabled = 1; s->key = key; s->last_updated = getTick(); if (pos == -1) pos = s->len; if (pos + len >= s->max_size) // make sure we do not overflow the data buffer len = s->max_size - pos; s->len = pos + len; if (pos == 0) { s->prev_no_change = s->no_change; s->no_change = 1; } if (new_key) s->no_change = 0; if (memcmp(s->data + pos, data, len) != 0) s->no_change = 0; memcpy(s->data + pos, data, len); return 0; }
PreciseTime HardwareTimer::getTime() { if (!__valid) return PreciseTime(); uint32_t tick = getTick(); uint32_t converted_ticks = tick * __tickValue; switch (__tickUnits) { default: case ns: return PreciseTime::from_ns(converted_ticks); case us: return PreciseTime::from_us(converted_ticks); case ms: return PreciseTime::from_ms(converted_ticks); case s: return PreciseTime::from_s(converted_ticks); case m: return PreciseTime::from_m(converted_ticks); case h: return PreciseTime::from_h(converted_ticks); } }
void *select_and_execute(void *arg) { fd_set io; int i, rv, rlen, les, es; unsigned char buf[2001]; int err; struct pollfd pf[MAX_SOCKS]; int64_t lt, c_time; int read_ok; char ra[50]; if (arg) thread_name = (char *) arg; else thread_name = "main"; tid = get_tid(); les = 1; es = 0; lt = getTick(); memset(&pf, -1, sizeof(pf)); LOG("Starting select_and_execute on thread ID %x, thread_name %s", tid, thread_name); while (run_loop) { c_time = getTick(); es = 0; clean_mutexes(); for (i = 0; i < max_sock; i++) if (s[i] && s[i]->enabled && s[i]->tid == tid) { pf[i].fd = s[i]->sock; pf[i].events = s[i]->events; pf[i].revents = 0; s[i]->last_poll = c_time; es++; } else { pf[i].fd = -1; pf[i].events = pf[i].revents = 0; } i = -1; if (les == 0 && es == 0 && tid != main_tid) { LOG("No enabled sockets for Thread ID %lx name %s ... exiting ", tid, thread_name); break; } les = es; // LOG("start select"); if ((rv = poll(pf, max_sock, 100)) < 0) { LOG("select_and_execute: select() error %d: %s", errno, strerror(errno)); continue; } // LOG("select returned %d",rv); if (rv > 0) while (++i < max_sock) if ((pf[i].fd >= 0) && pf[i].revents) { sockets *ss = s[i]; if (!ss) continue; c_time = getTick(); LOGL(6, "event on socket index %d handle %d type %d (poll fd:%d, revents=%d)", i, ss->sock, ss->type, pf[i].fd, pf[i].revents); sockets_lock(ss); if (pf[i].revents & POLLOUT) { ss->events &= ~POLLOUT; } if (!ss->buf || ss->buf == buf) { ss->buf = buf; ss->lbuf = sizeof(buf) - 1; ss->rlen = 0; } if (ss->rlen >= ss->lbuf) { LOG( "Socket buffer full, handle %d, sock_id %d, type %d, lbuf %d, rlen %d, ss->buf = %p, buf %p", ss->sock, i, ss->type, ss->lbuf, ss->rlen, ss->buf, buf); ss->rlen = 0; } rlen = 0; if (opts.bw > 0 && bw > opts.bw && ss->type == TYPE_DVR) { int64_t ms = 1000 - c_time + bwtt; if (bwnotify++ == 0) LOG( "capping %d sock %d for the next %jd ms, sleeping for the next %jd ms", i, ss->sock, ms, ms / 50); if (ms > 50) usleep(ms * 20); sockets_unlock(ss); continue; } read_ok = ss->read(ss->sock, &ss->buf[ss->rlen], ss->lbuf - ss->rlen, ss, &rlen); if (opts.log >= 1) { int64_t now = getTick(); if (now - c_time > 100) LOG( "WARNING: read on socket id %d, handle %d, took %jd ms", ss->id, ss->sock, now - c_time); } err = 0; if (rlen < 0) err = errno; if (rlen > 0) ss->rtime = c_time; if (read_ok && rlen >= 0) ss->rlen += rlen; else ss->rlen = 0; //force 0 at the end of the string if (ss->lbuf >= ss->rlen) ss->buf[ss->rlen] = 0; LOGL(6, "Read %s %d (rlen:%d/total:%d) bytes from %d -> %p - iteration %d action %p", read_ok ? "OK" : "NOK", rlen, ss->rlen, ss->lbuf, ss->sock, ss->buf, it++, ss->action); if (((ss->rlen > 0) || err == EWOULDBLOCK) && ss->action && (ss->type != TYPE_SERVER)) ss->action(ss); sockets_unlock(ss); if (!read_ok && ss->type != TYPE_SERVER) { char *err_str; char *types[] = { "udp", "tcp", "server", "http", "rtsp", "dvr" }; if (rlen == 0) { err = 0; err_str = "Close"; } else if (err == EOVERFLOW) err_str = "EOVERFLOW"; else if (err == EWOULDBLOCK) err_str = "Connected"; else err_str = strerror(err); if (ss->type == TYPE_RTCP || ss->sock == SOCK_TIMEOUT) { LOG( "ignoring error on sock_id %d handle %d type %d error %d : %s", ss->id, ss->sock, ss->type, err, err_str); continue; // do not close the RTCP socket, we might get some errors here but ignore them } LOG( "select_and_execute[%d]: %s on socket %d (sid:%d) from %s:%d - type %s errno %d", i, err_str, ss->sock, ss->sid, get_socket_rhost(ss->id, ra, sizeof(ra)), ntohs(ss->sa.sin_port), types[ss->type], err); if (err == EOVERFLOW || err == EWOULDBLOCK) continue; if (err == EAGAIN) { ss->err++; if (ss->err < 10) continue; } sockets_del(i); LOG("Delete socket %d done: sid %d", i, ss->sid); continue; } // ss->err = 0; } // checking every 60seconds for idle connections - or if select times out c_time = getTick(); if (rv == 0 || (c_time - lt >= 200)) { sockets *ss; lt = c_time; i = -1; while (++i < max_sock) if ((ss = get_sockets(i)) && (ss->tid == tid) && ((ss->timeout_ms > 0 && lt - ss->rtime > ss->timeout_ms) || (ss->timeout_ms == 1))) { if (ss->timeout) { int rv; if (ss->sock == SOCK_TIMEOUT) ss->rtime = getTick(); sockets_lock(ss); rv = ss->timeout(ss); sockets_unlock(ss); if (rv) sockets_del(i); } if (!ss->timeout) sockets_del(i); } } } clean_mutexes(); if (tid == main_tid) LOG("The main loop ended, run_loop = %d", run_loop); add_join_thread(tid); return NULL; }
int dvb_tune(int aid, transponder * tp) { int bclear, bpol, iProp = 0; adapter *ad = get_adapter(aid); int fd_frontend = ad->fe; int freq = tp->freq; struct dtv_property p_cmd[20]; struct dtv_properties p = { .num = 0, .props = p_cmd }; struct dvb_frontend_event ev; struct dtv_property p_clear[] = { { .cmd = DTV_CLEAR }, }; struct dtv_properties cmdseq_clear = { .num = 1, .props = p_clear }; memset(p_cmd, 0, sizeof(p_cmd)); bclear = getTick(); if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq_clear)) == -1) { LOG("FE_SET_PROPERTY DTV_CLEAR failed for fd %d: %s", fd_frontend, strerror(errno)); // return -1; } switch (tp->sys) { case SYS_DVBS: case SYS_DVBS2: bpol = getTick(); freq = setup_switch(fd_frontend, tp); if (freq < MIN_FRQ_DVBS || freq > MAX_FRQ_DVBS) LOG_AND_RETURN(-404, "Frequency %d is not within range ", freq) ADD_PROP(DTV_SYMBOL_RATE, tp->sr) ADD_PROP(DTV_INNER_FEC, tp->fec) ADD_PROP(DTV_PILOT, tp->plts) ADD_PROP(DTV_ROLLOFF, tp->ro) ADD_PROP(DTV_STREAM_ID, tp->plp) LOG( "tuning to %d(%d) pol: %s (%d) sr:%d fec:%s delsys:%s mod:%s rolloff:%s pilot:%s, ts clear=%d, ts pol=%d", tp->freq, freq, get_pol(tp->pol), tp->pol, tp->sr, fe_fec[tp->fec], fe_delsys[tp->sys], fe_modulation[tp->mtype], fe_rolloff[tp->ro], fe_pilot[tp->plts], bclear, bpol) break; case SYS_DVBT: case SYS_DVBT2: if (tp->freq < MIN_FRQ_DVBT || tp->freq > MAX_FRQ_DVBT) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_BANDWIDTH_HZ, tp->bw) ADD_PROP(DTV_CODE_RATE_HP, tp->fec) ADD_PROP(DTV_CODE_RATE_LP, tp->fec) ADD_PROP(DTV_GUARD_INTERVAL, tp->gi) ADD_PROP(DTV_TRANSMISSION_MODE, tp->tmode) ADD_PROP(DTV_HIERARCHY, HIERARCHY_AUTO) ADD_PROP(DTV_STREAM_ID, tp->plp & 0xFF) LOG( "tuning to %d delsys: %s bw:%d inversion:%s mod:%s fec:%s guard:%s transmission: %s, ts clear = %d", freq, fe_delsys[tp->sys], tp->bw, fe_specinv[tp->inversion], fe_modulation[tp->mtype], fe_fec[tp->fec], fe_gi[tp->gi], fe_tmode[tp->tmode], bclear) break; case SYS_DVBC2: case SYS_DVBC_ANNEX_A: if (tp->freq < MIN_FRQ_DVBC || tp->freq > MAX_FRQ_DVBC) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_SYMBOL_RATE, tp->sr) ADD_PROP(DTV_STREAM_ID, ((tp->ds & 0xFF) << 8) | (tp->plp & 0xFF)) // valid for DD DVB-C2 devices LOG("tuning to %d sr:%d specinv:%s delsys:%s mod:%s ts clear =%d", freq, tp->sr, fe_specinv[tp->inversion], fe_delsys[tp->sys], fe_modulation[tp->mtype], bclear) break; case SYS_ATSC: case SYS_DVBC_ANNEX_B: if (tp->freq < MIN_FRQ_DVBC || tp->freq > MAX_FRQ_DVBC) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) if (tp->mtype == 0) tp->mtype = QAM_AUTO; freq = freq * 1000; LOG("tuning to %d delsys:%s mod:%s specinv:%s ts clear=%d", freq, fe_delsys[tp->sys], fe_modulation[tp->mtype], fe_specinv[tp->inversion], bclear) break; case SYS_ISDBT: if (tp->freq < MIN_FRQ_DVBT || tp->freq > MAX_FRQ_DVBT) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_ISDBT_PARTIAL_RECEPTION, 0) ADD_PROP(DTV_BANDWIDTH_HZ, tp->bw) // ADD_PROP(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1); // ADD_PROP(DTV_ISDBT_LAYER_ENABLED, 1); LOG("tuning to %d delsys: %s bw:%d inversion:%s , ts clear = %d", freq, fe_delsys[tp->sys], tp->bw, fe_specinv[tp->inversion], bclear) ; break; default: LOG("tuninng to unknown delsys: %s freq %s ts clear = %d", freq, fe_delsys[tp->sys], bclear) break; } ADD_PROP(DTV_FREQUENCY, freq) ADD_PROP(DTV_INVERSION, tp->inversion) ADD_PROP(DTV_MODULATION, tp->mtype); ADD_PROP(DTV_DELIVERY_SYSTEM, tp->sys); ADD_PROP(DTV_TUNE, 0) p.num = iProp; /* discard stale QPSK events */ while (1) { if (ioctl(fd_frontend, FE_GET_EVENT, &ev) == -1) break; } if ((ioctl(fd_frontend, FE_SET_PROPERTY, &p)) == -1) if (ioctl(fd_frontend, FE_SET_PROPERTY, &p) == -1) { perror("FE_SET_PROPERTY TUNE failed"); LOG("set property failed"); return -404; } return 0; } int dvb_set_pid(adapter *a, uint16_t i_pid) { char buf[100]; int fd; int hw, ad; hw = a->pa; ad = a->fn; if (i_pid > 8192) LOG_AND_RETURN(-1, "pid %d > 8192 for /dev/dvb/adapter%d/demux%d", i_pid, hw, ad); sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); if ((fd = open(buf, O_RDWR | O_NONBLOCK)) < 0) { LOG("Could not open demux device /dev/dvb/adapter%d/demux%d: %s ", hw, ad, strerror (errno)); return -1; } struct dmx_pes_filter_params s_filter_params; memset(&s_filter_params, 0, sizeof(s_filter_params)); s_filter_params.pid = i_pid; s_filter_params.input = DMX_IN_FRONTEND; s_filter_params.output = DMX_OUT_TS_TAP; s_filter_params.flags = DMX_IMMEDIATE_START; s_filter_params.pes_type = DMX_PES_OTHER; if (ioctl(fd, DMX_SET_PES_FILTER, &s_filter_params) < 0) { int pids[MAX_PIDS]; int ep; ep = get_enabled_pids(a, (int *) pids, MAX_PIDS); LOG("failed setting filter on %d (%s), enabled pids %d", i_pid, strerror (errno), ep); return -1; } LOG("setting filter on PID %d for fd %d", i_pid, fd); return fd; }
// return elapsed time from console reset (1/256 second based) u32 getTime(u16 fromTick) { if (fromTick) return (getTick() * TICKPERSECOND) >> 8; else return getSubTick() / TICKPERSECOND;
int init_hw(int i) { char name[100]; adapter *ad; if (i < 0 || i >= MAX_ADAPTERS) return 1; if (a[i] && a[i]->enabled) return 1; if (!a[i]) return 1; ad = a[i]; mutex_init(&ad->mutex); mutex_lock(&ad->mutex); if (ad->force_disable) goto NOK; if (ad->enabled) goto NOK; ad->sock = -1; ad->id = i; ad->fe_sock = -1; ad->sock = -1; if (ad->enabled) { goto NOK; } if (ad->open(ad)) { init_complete = 0; goto NOK; } ad->enabled = 1; if (!ad->buf) ad->buf = malloc1(opts.adapter_buffer + 10); if (!ad->buf) { LOG( "memory allocation failed for %d bytes failed, adapter %d, trying %d bytes", opts.adapter_buffer, i, ADAPTER_BUFFER); opts.adapter_buffer = ADAPTER_BUFFER; ad->buf = malloc1(opts.adapter_buffer + 10); if (!ad->buf) { LOG("memory allocation failed for %d bytes failed, adapter %d", opts.adapter_buffer, i); close_adapter(i); } goto NOK; } memset(ad->buf, 0, opts.adapter_buffer + 1); init_dvb_parameters(&ad->tp); mark_pids_deleted(i, -1, NULL); update_pids(i); ad->delsys(i, ad->fe, ad->sys); ad->master_sid = -1; ad->sid_cnt = 0; ad->pid_err = ad->dec_err = 0; ad->new_gs = 0; ad->force_close = 0; ad->ca_mask = 0; ad->rtime = getTick(); ad->sock = sockets_add(ad->dvr, NULL, i, TYPE_DVR, (socket_action) read_dmx, (socket_action) close_adapter_for_socket, (socket_action) adapter_timeout); memset(ad->buf, 0, opts.adapter_buffer + 1); set_socket_buffer(ad->sock, (unsigned char*) ad->buf, opts.adapter_buffer); sockets_timeout(ad->sock, ADAPTER_TIMEOUT); snprintf(ad->name, sizeof(ad->name), "AD%d", i); set_socket_thread(ad->sock, start_new_thread(ad->name)); tables_init_device(ad); if (ad->post_init) ad->post_init(ad); // set_sock_lock(ad->sock, &ad->mutex); // locks automatically the adapter on reading from the DVR LOG("done opening adapter %i fe_sys %d %d %d %d", i, ad->sys[0], ad->sys[1], ad->sys[2], ad->sys[3]); OK: mutex_unlock(&ad->mutex); return 0; NOK: mutex_unlock(&ad->mutex); return 1; }
void Screen::rollCredits() { uint32 loopingMusicId = _vm->_sound->getLoopingMusicId(); // Prepare for the credits by fading down, stoping the music, etc. _vm->_mouse->setMouse(0); _vm->_sound->muteFx(true); _vm->_sound->muteSpeech(true); waitForFade(); fadeDown(); waitForFade(); _vm->_mouse->closeMenuImmediately(); // There are three files which I believe are involved in showing the // credits: // // credits.bmp - The "Smacker" logo, stored as follows: // // width 2 bytes, little endian // height 2 bytes, little endian // palette 3 * 256 bytes // data width * height bytes // // Note that the maximum colour component in the palette is 0x3F. // This is the same resolution as the _paletteMatch table. I doubt // that this is a coincidence, but let's use the image palette // directly anyway, just to be safe. // // credits.clu - The credits text (credits.txt in PSX version) // // This is simply a text file with CRLF line endings. // '^' is not shown, but used to mark the center of the line. // '@' is used as a placeholder for the "Smacker" logo. At least // when it appears alone. // Remaining lines are centered. // The German version also contains character code 9 for no // apparent reason. We ignore them. // // fonts.clu - The credits font? // // FIXME: At this time I don't know how to interpret fonts.clu. For // now, let's just the standard speech font instead. SpriteInfo spriteInfo; Common::File f; int i; spriteInfo.isText = false; // Read the "Smacker" logo uint16 logoWidth = 0; uint16 logoHeight = 0; byte *logoData = NULL; byte palette[256 * 3]; if (f.open("credits.bmp")) { logoWidth = f.readUint16LE(); logoHeight = f.readUint16LE(); for (i = 0; i < 256; i++) { palette[i * 3 + 0] = f.readByte() << 2; palette[i * 3 + 1] = f.readByte() << 2; palette[i * 3 + 2] = f.readByte() << 2; } logoData = (byte *)malloc(logoWidth * logoHeight); f.read(logoData, logoWidth * logoHeight); f.close(); } else { warning("Can't find credits.bmp"); memset(palette, 0, sizeof(palette)); palette[14 * 3 + 0] = 252; palette[14 * 3 + 1] = 252; palette[14 * 3 + 2] = 252; } setPalette(0, 256, palette, RDPAL_INSTANT); // Read the credits text Common::Array<CreditsLine *> creditsLines; int lineCount = 0; int lineTop = 400; int paragraphStart = 0; bool hasCenterMark = false; if (Sword2Engine::isPsx()) { if (!f.open("credits.txt")) { warning("Can't find credits.txt"); free(logoData); return; } } else { if (!f.open("credits.clu")) { warning("Can't find credits.clu"); free(logoData); return; } } while (1) { char buffer[80]; char *line = f.readLine(buffer, sizeof(buffer)); if (line) { // Replace invalid character codes prevent the 'dud' // symbol from showing up in the credits. for (byte *ptr = (byte *)line; *ptr; ptr++) { switch (*ptr) { case 9: // The German credits contain these. // Convert them to spaces. *ptr = 32; break; case 10: // LF is treated as end of line. *ptr = 0; break; case 170: // The Spanish credits contain these. // Convert them to periods. *ptr = '.'; default: break; } } } if (!line || *line == 0) { if (!hasCenterMark) { for (i = paragraphStart; i < lineCount; i++) creditsLines[i]->type = LINE_CENTER; } paragraphStart = lineCount; hasCenterMark = false; if (paragraphStart == lineCount) lineTop += CREDITS_LINE_SPACING; if (!line) break; continue; } char *center_mark = strchr(line, '^'); if (center_mark) { // The current paragraph has at least one center mark. hasCenterMark = true; if (center_mark != line) { creditsLines.push_back(new CreditsLine); // The center mark is somewhere inside the // line. Split it into left and right side. *center_mark = 0; creditsLines[lineCount]->top = lineTop; creditsLines[lineCount]->height = CREDITS_FONT_HEIGHT; creditsLines[lineCount]->type = LINE_LEFT; creditsLines[lineCount]->str = strdup(line); lineCount++; *center_mark = '^'; } line = center_mark; } creditsLines.push_back(new CreditsLine); creditsLines[lineCount]->top = lineTop; if (*line == '^') { creditsLines[lineCount]->type = LINE_RIGHT; line++; } else creditsLines[lineCount]->type = LINE_LEFT; if (strcmp(line, "@") == 0) { creditsLines[lineCount]->height = logoHeight; lineTop += logoHeight; } else { creditsLines[lineCount]->height = CREDITS_FONT_HEIGHT; lineTop += CREDITS_LINE_SPACING; } creditsLines[lineCount]->str = strdup(line); lineCount++; } f.close(); // We could easily add some ScummVM stuff to the credits, if we wanted // to. On the other hand, anyone with the attention span to actually // read all the credits probably already knows. :-) // Start the music and roll the credits // The credits music (which can also be heard briefly in the "carib" // cutscene) is played once. _vm->_sound->streamCompMusic(309, false); clearScene(); fadeUp(0); spriteInfo.scale = 0; spriteInfo.scaledWidth = 0; spriteInfo.scaledHeight = 0; spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS; spriteInfo.blend = 0; int startLine = 0; int scrollPos = 0; bool abortCredits = false; int scrollSteps = lineTop + CREDITS_FONT_HEIGHT; uint32 musicStart = getTick(); // Ideally the music should last just a tiny bit longer than the // credits. Note that musicTimeRemaining() will return 0 if the music // is muted, so we need a sensible fallback for that case. uint32 musicLength = MAX((int32)(1000 * (_vm->_sound->musicTimeRemaining() - 3)), 25 * (int32)scrollSteps); while (scrollPos < scrollSteps && !_vm->shouldQuit()) { clearScene(); for (i = startLine; i < lineCount; i++) { if (!creditsLines[i]) continue; // Free any sprites that have scrolled off the screen if (creditsLines[i]->top + creditsLines[i]->height < scrollPos) { debug(2, "Freeing line %d: '%s'", i, creditsLines[i]->str); delete creditsLines[i]; creditsLines[i] = NULL; startLine = i + 1; } else if (creditsLines[i]->top < scrollPos + 400) { if (!creditsLines[i]->sprite) { debug(2, "Creating line %d: '%s'", i, creditsLines[i]->str); creditsLines[i]->sprite = _vm->_fontRenderer->makeTextSprite((byte *)creditsLines[i]->str, 600, 14, _vm->_speechFontId, 0); } FrameHeader frame; frame.read(creditsLines[i]->sprite); spriteInfo.y = creditsLines[i]->top - scrollPos; spriteInfo.w = frame.width; spriteInfo.h = frame.height; spriteInfo.data = creditsLines[i]->sprite + FrameHeader::size(); spriteInfo.isText = true; switch (creditsLines[i]->type) { case LINE_LEFT: spriteInfo.x = RENDERWIDE / 2 - 5 - frame.width; break; case LINE_RIGHT: spriteInfo.x = RENDERWIDE / 2 + 5; break; case LINE_CENTER: if (strcmp(creditsLines[i]->str, "@") == 0) { spriteInfo.data = logoData; spriteInfo.x = (RENDERWIDE - logoWidth) / 2; spriteInfo.w = logoWidth; spriteInfo.h = logoHeight; } else spriteInfo.x = (RENDERWIDE - frame.width) / 2; break; } if (spriteInfo.data) drawSprite(&spriteInfo); } else break; } updateDisplay(); KeyboardEvent *ke = _vm->keyboardEvent(); if (ke && ke->kbd.keycode == Common::KEYCODE_ESCAPE) { if (!abortCredits) { abortCredits = true; fadeDown(); } } if (abortCredits && getFadeStatus() == RDFADE_BLACK) break; _vm->sleepUntil(musicStart + (musicLength * scrollPos) / scrollSteps + _pauseTicks); scrollPos++; } // We're done. Clean up and try to put everything back where it was // before the credits. for (i = 0; i < lineCount; i++) { delete creditsLines[i]; } free(logoData); if (!abortCredits) { fadeDown(); // The music should either have stopped or be about to stop, so // wait for it to really happen. while (_vm->_sound->musicTimeRemaining() && !_vm->shouldQuit()) { updateDisplay(false); _vm->_system->delayMillis(100); } } if (_vm->shouldQuit()) return; waitForFade(); _vm->_sound->muteFx(false); _vm->_sound->muteSpeech(false); if (loopingMusicId) _vm->_sound->streamCompMusic(loopingMusicId, true); else _vm->_sound->stopMusic(false); if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing()) _vm->_mouse->setMouse(NORMAL_MOUSE_ID); if (_vm->_logic->readVar(DEAD)) _vm->_mouse->buildSystemMenu(); }
void Screen::buildDisplay() { if (_thisScreen.new_palette) { // start the layer palette fading up startNewPalette(); // should be reset to zero at start of each screen change _largestLayerArea = 0; _largestSpriteArea = 0; } // Does this ever happen? if (!_thisScreen.background_layer_id) return; // there is a valid screen to run setScrollTarget(_thisScreen.scroll_offset_x, _thisScreen.scroll_offset_y); _vm->_mouse->animateMouse(); startRenderCycle(); byte *file = _vm->_resman->openResource(_thisScreen.background_layer_id); MultiScreenHeader screenLayerTable; memset(&screenLayerTable, 0, sizeof(screenLayerTable)); if (!Sword2Engine::isPsx()) // On PSX version, there would be nothing to read here screenLayerTable.read(file + ResHeader::size()); // Render at least one frame, but if the screen is scrolling, and if // there is time left, we will render extra frames to smooth out the // scrolling. do { // first background parallax + related anims if (Sword2Engine::isPsx() || screenLayerTable.bg_parallax[0]) { // No need to check on PSX version renderParallax(_vm->fetchBackgroundParallaxLayer(file, 0), 0); drawBackPar0Frames(); } // second background parallax + related anims if (!Sword2Engine::isPsx() && screenLayerTable.bg_parallax[1]) { // Nothing here in PSX version renderParallax(_vm->fetchBackgroundParallaxLayer(file, 1), 1); drawBackPar1Frames(); } // normal backround layer (just the one!) renderParallax(_vm->fetchBackgroundLayer(file), 2); // sprites & layers drawBackFrames(); // background sprites drawSortFrames(file); // sorted sprites & layers drawForeFrames(); // foreground sprites // first foreground parallax + related anims if (Sword2Engine::isPsx() || screenLayerTable.fg_parallax[0]) { renderParallax(_vm->fetchForegroundParallaxLayer(file, 0), 3); drawForePar0Frames(); } // second foreground parallax + related anims if (!Sword2Engine::isPsx() && screenLayerTable.fg_parallax[1]) { renderParallax(_vm->fetchForegroundParallaxLayer(file, 1), 4); drawForePar1Frames(); } _vm->_debugger->drawDebugGraphics(); _vm->_fontRenderer->printTextBlocs(); _vm->_mouse->processMenu(); updateDisplay(); _frameCount++; if (getTick() > _cycleTime) { _fps = _frameCount; _frameCount = 0; _cycleTime = getTick() + 1000; } } while (!endRenderCycle()); _vm->_resman->closeResource(_thisScreen.background_layer_id); }
void MidiInfo::readFile(int mode) { cur = 0; if((mf = fopen(fileName, "rb")) == NULL) //Try open file return; fseek(mf, 0L, SEEK_END); dim = ftell(mf); //Get file dim. //Start copy file in memory by = new unsigned char[dim]; rewind(mf); fread(by, sizeof(unsigned char), dim, mf); unsigned char cs; unsigned char* info; unsigned char dims,type; //Check if it's a midi file if(by[(cur)] == 0x4d && by[(cur + 1)] == 0x54 && by[(cur) + 2] == 0x68 && by[(cur) + 3] == 0x64) valid=true; else return; while(by[(++cur)] != 0x4d){} if(mode == 1) { unsigned char* bres = new unsigned char[2]; bres[0] = by[cur-2]; bres[1] = by[cur-1]; resolution=Utilities::convertResolution(bres); } this->mode = mode; if(mode == 0) il = new Tick[maxTick + 1]; //Start fetching file while(cur < dim){ if(by[(cur)] == 0x4d && by[(cur + 1)] == 0x54 && by[(cur) + 2] == 0x72 && by[(cur) + 3] == 0x6b) { curTick=0; cur+=8; } getTick(); cs=by[cur] & 0xf0; switch(cs){ case 0xf0: if(by[cur]==0xff) { type=by[++cur]; dims=by[++cur]; if(mode!=1){ info=new unsigned char[dims+3]; info[0]=0xff; info[1]=type; info[2]=dims; } for(int i=0;i<dims;i++) { if(mode!=1) info[i+3]=by[++cur]; else ++cur; } if(mode==1 && type==0x51) tl->add(new TempoNode(curTick,Utilities::convertTempo(by+(cur-dims+1)))); cur++; if(mode==0)il[curTick].add(info); if(mode==2)ir->getInfo(curTick,info); } else if(by[cur]==0xf0) { dims=by[++cur]; if(mode!=1){ info=new unsigned char[dims+2]; info[0]=0xf0; info[1]=dims; } for(int i=0;i<dims;i++) { if(mode!=1) info[i+2]=by[++cur]; else ++cur; } cur++; if(mode==0)il[curTick].add(info); if(mode==2)ir->getInfo(curTick,info); } break; case 0x80: get3ByteInfo(); break; case 0x90: get3ByteInfo(); break; case 0xB0: get3ByteInfo(); break; case 0xC0: get2ByteInfo(); break; case 0xE0: get3ByteInfo(); break; case 0xA0: get3ByteInfo(); break; case 0xD0: get3ByteInfo(); break; } if(mode==1 && curTick>maxTick) maxTick=curTick; } if(mode==1){ unsigned int ticksecond,nextick; TempoNode* t=tl->t; do{ if((t->next)==NULL) nextick=maxTick; else nextick=(t->next)->tick; nextick=nextick-(t->tick); ticksecond=(unsigned int)(((t->tempo)*resolution)/60); seclength+=(unsigned int)(nextick/ticksecond); t=(t->next); }while(t!=NULL); fclose(mf); } if(mode==1) delete []by; }