Example #1
0
void clsTracking2D::resetBG()
{
        resetTracking();
        /*if(paramsInt["bg"] == BG_BGCodeBookModel)
        {
                INFOMSG(("background resetted"));
                BgCbNrframes = 0;
        }
        else
        {
                if(paramsInt["bg"] == BG_SEG)
                {
                        if(updateBgModel)
                        {
                                INFOMSG(("Background update is on\n"));
                        }
                        else
                        {
                                INFOMSG(("Background update is off\n"));
                        }
                        updateBgModel = !updateBgModel;
                }
                else
                {
                        INFOMSG(("Nothing to do."));
                }
        }*/
}
Example #2
0
bool MidiParser::setTrack(int track) {
	if (track < 0 || track >= _num_tracks)
		return false;
	// We allow restarting the track via setTrack when
	// it isn't playing anymore. This allows us to reuse
	// a MidiParser when a track has finished and will
	// be restarted via setTrack by the client again.
	// This isn't exactly how setTrack behaved before though,
	// the old MidiParser code did not allow setTrack to be
	// used to restart a track, which was already finished.
	//
	// TODO: Check if any engine has problem with this
	// handling, if so we need to find a better way to handle
	// track restarts. (KYRA relies on this working)
	else if (track == _active_track && isPlaying())
		return true;

	if (_smartJump)
		hangAllActiveNotes();
	else
		allNotesOff();

	resetTracking();
	memset(_active_notes, 0, sizeof(_active_notes));
	_active_track = track;
	_position._play_pos = _tracks[track];
	parseNextEvent(_next_event);
	return true;
}
Example #3
0
void RobotSocket::internalInit(void)
{
	//关闭时无需执行其他函数
	myCloseFunctor = NULL;
	sprintf(myIPString, "none");
	//清空计数器
#ifdef COUNT_DATA
	resetTracking(); 
#endif
}
Example #4
0
bool MidiParser_S1D::loadMusic(byte *data, uint32 size) {
	unloadMusic();

	if (!size)
		return false;

	// The original actually just ignores the first two bytes.
	byte *pos = data;
	if (*pos == 0xFC) {
		// SysEx found right at the start
		// this seems to happen since Elvira 2, we ignore it
		// 3rd byte after the SysEx seems to be saved into a global

		// We expect at least 4 bytes in total
		if (size < 4)
			return false;

		byte skipOffset = pos[2]; // get second byte after the SysEx
		// pos[1] seems to have been ignored
		// pos[3] is saved into a global inside the original interpreters

		// Waxworks + Simon 1 demo typical header is:
		//  0xFC 0x29 0x07 0x01 [0x00/0x01]
		// Elvira 2 typical header is:
		//  0xFC 0x04 0x06 0x06

		if (skipOffset >= 6) {
			// should be at least 6, so that we skip over the 2 size bytes and the
			// smallest SysEx possible
			skipOffset -= 2; // 2 size bytes were already read by previous code outside of this method

			if (size <= skipOffset) // Skip to the end of file? -> something is not correct
				return false;

			// Do skip over the bytes
			pos += skipOffset;
		} else {
			warning("MidiParser_S1D: unexpected skip offset in music file");
		}
	}

	// And now we're at the actual data. Only one track.
	_numTracks = 1;
	_data = pos;
	_tracks[0] = pos;

	// Note that we assume the original data passed in
	// will persist beyond this call, i.e. we do NOT
	// copy the data to our own buffer. Take warning....
	resetTracking();
	setTempo(666667);
	setTrack(0);
	return true;
}
Example #5
0
void ArSocket::internalInit(void)
{
  myCloseFunctor = NULL;
  myStringAutoEcho = true;
  myStringEcho = false;
  myStringPosLast = 0;
  myStringPos = 0;
  myStringGotComplete = false;
  myStringBufEmpty[0] = '\0';
  myStringGotEscapeChars = false;
  myStringHaveEchoed = false;
  sprintf(myIPString, "none");
  resetTracking();
}
Example #6
0
void MidiParser::unloadMusic() {
	resetTracking();
	allNotesOff();
	_num_tracks = 0;
	_active_track = 255;
	_abort_parse = true;

	if (_centerPitchWheelOnUnload) {
		// Center the pitch wheels in preparation for the next piece of
		// music. It's not safe to do this from within allNotesOff(),
		// and might not even be safe here, so we only do it if the
		// client has explicitly asked for it.

		if (_driver) {
			for (int i = 0; i < 16; ++i) {
				sendToDriver(0xE0 | i, 0, 0x40);
			}
		}
	}
}
Example #7
0
bool MidiParser_RO::loadMusic (byte *data, uint32 size) {
	unloadMusic();
	byte *pos = data;

	if (memcmp (pos, "RO", 2)) {
		error("'RO' header expected but found '%c%c' instead", pos[0], pos[1]);
		return false;
	}

	_num_tracks = 1;
	_ppqn = 120;
	_tracks[0] = pos + 2;
	_markerCount = _lastMarkerCount = 0;

	// Note that we assume the original data passed in
	// will persist beyond this call, i.e. we do NOT
	// copy the data to our own buffer. Take warning....
	resetTracking();
	setTempo (500000);
	setTrack (0);
	return true;
}
Example #8
0
void ArSocket::internalInit(void)
{
  myReadStringMutex.setLogName("ArMutex::myReadStringMutex");
  myWriteStringMutex.setLogName("ArMutex::myWriteStringMutex");
  myCloseFunctor = NULL;
  myStringAutoEcho = true;
  myStringEcho = false;
  myStringPosLast = 0;
  myStringPos = 0;
  myStringGotComplete = false;
  myStringBufEmpty[0] = '\0';
  myStringGotEscapeChars = false;
  myStringHaveEchoed = false;
  myLastStringReadTime.setToNow();
  myLogWriteStrings = false;
  sprintf(myRawIPString, "none");
  myIPString = "";
  myBadWrite = false;
  myBadRead = false;
  myStringIgnoreReturn = false;
  myStringWrongEndChars = false;
  myErrorTracking = false;
  resetTracking();
}
Example #9
0
bool MidiParser_S1D::loadMusic(byte *data, uint32 size) {
	unloadMusic();

	byte *pos = data;
	if (*(pos++) != 0xFC)
		debug(1, "Expected 0xFC header but found 0x%02X instead", (int) *pos);

	// The next 3 bytes MIGHT be tempo, but we skip them and use the default.
//	setTempo (*(pos++) | (*(pos++) << 8) | (*(pos++) << 16));
	pos += 3;

	// And now we're at the actual data. Only one track.
	_num_tracks = 1;
	_data = pos;
	_tracks[0] = pos;

	// Note that we assume the original data passed in
	// will persist beyond this call, i.e. we do NOT
	// copy the data to our own buffer. Take warning....
	resetTracking();
	setTempo(666667);
	setTrack(0);
	return true;
}
Example #10
0
bool MidiParser_SMF::loadMusic(byte *data, uint32 size) {
	uint32 len;
	byte midi_type;
	uint32 total_size;
	bool isGMF;

	unloadMusic();
	byte *pos = data;
	isGMF = false;

	if (!memcmp(pos, "RIFF", 4)) {
		// Skip the outer RIFF header.
		pos += 8;
	}

	if (!memcmp(pos, "MThd", 4)) {
		// SMF with MTHd information.
		pos += 4;
		len = read4high(pos);
		if (len != 6) {
			warning("MThd length 6 expected but found %d", (int)len);
			return false;
		}

		// Verify that this MIDI either is a Type 2
		// or has only 1 track. We do not support
		// multitrack Type 1 files.
		_num_tracks = pos[2] << 8 | pos[3];
		midi_type = pos[1];
		if (midi_type > 2 /*|| (midi_type < 2 && _num_tracks > 1)*/) {
			warning("No support for a Type %d MIDI with %d tracks", (int)midi_type, (int)_num_tracks);
			return false;
		}
		_ppqn = pos[4] << 8 | pos[5];
		pos += len;
	} else if (!memcmp(pos, "GMF\x1", 4)) {
		// Older GMD/MUS file with no header info.
		// Assume 1 track, 192 PPQN, and no MTrk headers.
		isGMF = true;
		midi_type = 0;
		_num_tracks = 1;
		_ppqn = 192;
		pos += 7; // 'GMD\x1' + 3 bytes of useless (translate: unknown) information
	} else {
		warning("Expected MThd or GMD header but found '%c%c%c%c' instead", pos[0], pos[1], pos[2], pos[3]);
		return false;
	}

	// Now we identify and store the location for each track.
	if (_num_tracks > ARRAYSIZE(_tracks)) {
		warning("Can only handle %d tracks but was handed %d", (int)ARRAYSIZE(_tracks), (int)_num_tracks);
		return false;
	}

	total_size = 0;
	int tracks_read = 0;
	while (tracks_read < _num_tracks) {
		if (memcmp(pos, "MTrk", 4) && !isGMF) {
			warning("Position: %p ('%c')", pos, *pos);
			warning("Hit invalid block '%c%c%c%c' while scanning for track locations", pos[0], pos[1], pos[2], pos[3]);
			return false;
		}

		// If needed, skip the MTrk and length bytes
		_tracks[tracks_read] = pos + (isGMF ? 0 : 8);
		if (!isGMF) {
			pos += 4;
			len = read4high(pos);
			total_size += len;
			pos += len;
		} else {
			// An SMF End of Track meta event must be placed
			// at the end of the stream.
			data[size++] = 0xFF;
			data[size++] = 0x2F;
			data[size++] = 0x00;
			data[size++] = 0x00;
		}
		++tracks_read;
	}

	// If this is a Type 1 MIDI, we need to now compress
	// our tracks down into a single Type 0 track.
	free(_buffer);
	_buffer = 0;

	if (midi_type == 1) {
		// FIXME: Doubled the buffer size to prevent crashes with the
		// Inherit the Earth MIDIs. Jamieson630 said something about a
		// better fix, but this will have to do in the meantime.
		_buffer = (byte *)malloc(size * 2);
		compressToType0();
		_num_tracks = 1;
		_tracks[0] = _buffer;
	}

	// Note that we assume the original data passed in
	// will persist beyond this call, i.e. we do NOT
	// copy the data to our own buffer. Take warning....
	resetTracking();
	setTempo(500000);
	setTrack(0);
	return true;
}
Example #11
0
bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool dontSendNoteOn) {
	if (_active_track >= _num_tracks)
		return false;

	Tracker currentPos(_position);
	EventInfo currentEvent(_next_event);

	resetTracking();
	_position._play_pos = _tracks[_active_track];
	parseNextEvent(_next_event);
	if (tick > 0) {
		while (true) {
			EventInfo &info = _next_event;
			if (_position._last_event_tick + info.delta >= tick) {
				_position._play_time += (tick - _position._last_event_tick) * _psec_per_tick;
				_position._play_tick = tick;
				break;
			}

			_position._last_event_tick += info.delta;
			_position._last_event_time += info.delta * _psec_per_tick;
			_position._play_tick = _position._last_event_tick;
			_position._play_time = _position._last_event_time;

			if (info.event == 0xFF) {
				if (info.ext.type == 0x2F) { // End of track
					_position = currentPos;
					_next_event = currentEvent;
					return false;
				} else {
					if (info.ext.type == 0x51 && info.length >= 3) // Tempo
						setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
					if (fireEvents)
						_driver->metaEvent(info.ext.type, info.ext.data, (uint16) info.length);
				}
			} else if (fireEvents) {
				if (info.event == 0xF0) {
					if (info.ext.data[info.length-1] == 0xF7)
						_driver->sysEx(info.ext.data, (uint16)info.length-1);
					else
						_driver->sysEx(info.ext.data, (uint16)info.length);
				} else {
					// The note on sending code is used by the SCUMM engine. Other engine using this code
					// (such as SCI) have issues with this, as all the notes sent can be heard when a song
					// is fast-forwarded.	Thus, if the engine requests it, don't send note on events.
					if (info.command() == 0x9 && dontSendNoteOn) {
						// Don't send note on; doing so creates a "warble" with some instruments on the MT-32.
						// Refer to patch #3117577
					} else {
						sendToDriver(info.event, info.basic.param1, info.basic.param2);
					}
				}
			}

			parseNextEvent(_next_event);
		}
	}

	if (stopNotes) {
		if (!_smartJump || !currentPos._play_pos) {
			allNotesOff();
		} else {
			EventInfo targetEvent(_next_event);
			Tracker targetPosition(_position);

			_position = currentPos;
			_next_event = currentEvent;
			hangAllActiveNotes();

			_next_event = targetEvent;
			_position = targetPosition;
		}
	}

	_abort_parse = true;
	return true;
}
Example #12
0
void MidiParser::stopPlaying() {
	allNotesOff();
	resetTracking();
}
AREXPORT ArServerClient::ArServerClient(
	ArSocket *tcpSocket, unsigned int udpPort, long authKey,
	long introKey, 	ArRetFunctor2<bool, ArNetPacket *, 
	struct sockaddr_in *> *sendUdpCallback,
	std::map<unsigned int, ArServerData *> *dataMap,
	const char *passwordKey, const char *serverKey,
	const ArServerUserInfo *userInfo, int rejecting, 
	const char *rejectingString, bool debugLogging,
	const char *serverClientName, bool logPasswordFailureVerbosely,
	bool allowSlowPackets, bool allowIdlePackets) :
  myProcessPacketCB(this, &ArServerClient::processPacket, NULL, true)
{
  ArNetPacket packet;

  // set our default to no command
  pushCommand(0);

  myAuthKey = authKey;
  myIntroKey = introKey;
  myTcpSocket.transfer(tcpSocket);
  myTcpSocket.setCloseCallback(tcpSocket->getCloseCallback());
  myTcpSocket.setNonBlock();
  myTcpReceiver.setSocket(&myTcpSocket);
  myTcpReceiver.setProcessPacketCB(&myProcessPacketCB);
  myTcpSender.setSocket(&myTcpSocket);

  mySendUdpCB = sendUdpCallback;
  myDataMap = dataMap;
  if (udpPort == 0)
    myTcpOnly = true;
  else
    myTcpOnly = false;
  mySentTcpOnly = myTcpOnly;

  myUserInfo = userInfo;
  myPasswordKey = passwordKey;
  myServerKey = serverKey;
  myRejecting = rejecting;
  if (rejectingString != NULL)
    myRejectingString = rejectingString;

  myDebugLogging = debugLogging;
  if (myDebugLogging)
    myVerboseLogLevel = ArLog::Normal;
  else
    myVerboseLogLevel = ArLog::Verbose;

  myTcpSender.setDebugLogging(myDebugLogging);

  myLogPrefix = serverClientName;
  myLogPrefix += ": ";
  myTcpSender.setLoggingPrefix(myLogPrefix.c_str());
  myTcpReceiver.setLoggingPrefix(myLogPrefix.c_str());

  myLogPasswordFailureVerbosely = logPasswordFailureVerbosely;

  mySlowPacketsMutex.setLogName("ArServerClient::mySlowPacketsMutex");
  myIdlePacketsMutex.setLogName("ArServerClient::myIdlePacketsMutex");

  myAllowSlowPackets = allowSlowPackets;
  myAllowIdlePackets = allowIdlePackets;

  setIdentifier(ArServerClientIdentifier());
  internalSwitchState(STATE_SENT_INTRO);

  packet.empty();
  packet.setCommand(ArServerCommands::INTRODUCTION);
  packet.strToBuf("alpha");
  packet.uByte2ToBuf(udpPort);
  packet.uByte4ToBuf(myAuthKey);
  packet.uByte4ToBuf(myIntroKey);
  packet.strToBuf(myPasswordKey.c_str());
  sendPacketTcp(&packet);

  mySlowIdleThread = NULL;

  myHaveSlowPackets = false;
  myHaveIdlePackets = false;
  
  myCreationTime.setToNow();

  resetTracking();
}
Example #14
0
bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
	uint32 i = 0;
	byte *start;
	uint32 len;
	uint32 chunk_len;
	char buf[32];

	_loopCount = -1;

	unloadMusic();
	byte *pos = data;

	if (!memcmp(pos, "FORM", 4)) {
		pos += 4;

		// Read length of
		len = read4high(pos);
		start = pos;

		// XDIRless XMIDI, we can handle them here.
		if (!memcmp(pos, "XMID", 4)) {
			warning("XMIDI doesn't have XDIR");
			pos += 4;
			_num_tracks = 1;
		} else if (memcmp(pos, "XDIR", 4)) {
			// Not an XMIDI that we recognise
			warning("Expected 'XDIR' but found '%c%c%c%c'", pos[0], pos[1], pos[2], pos[3]);
			return false;
		} else {
			// Seems Valid
			pos += 4;
			_num_tracks = 0;

			for (i = 4; i < len; i++) {
				// Read 4 bytes of type
				memcpy(buf, pos, 4);
				pos += 4;

				// Read length of chunk
				chunk_len = read4high(pos);

				// Add eight bytes
				i += 8;

				if (memcmp(buf, "INFO", 4)) {
					// Must align
					pos += (chunk_len + 1) & ~1;
					i += (chunk_len + 1) & ~1;
					continue;
				}

				// Must be at least 2 bytes long
				if (chunk_len < 2) {
					warning("Invalid chunk length %d for 'INFO' block", (int)chunk_len);
					return false;
				}

				_num_tracks = (byte)read2low(pos);

				if (chunk_len > 2) {
					warning("Chunk length %d is greater than 2", (int)chunk_len);
					pos += chunk_len - 2;
				}
				break;
			}

			// Didn't get to fill the header
			if (_num_tracks == 0) {
				warning("Didn't find a valid track count");
				return false;
			}

			// Ok now to start part 2
			// Goto the right place
			pos = start + ((len + 1) & ~1);

			if (memcmp(pos, "CAT ", 4)) {
				// Not an XMID
				warning("Expected 'CAT ' but found '%c%c%c%c'", pos[0], pos[1], pos[2], pos[3]);
				return false;
			}
			pos += 4;

			// Now read length of this track
			len = read4high(pos);

			if (memcmp(pos, "XMID", 4)) {
				// Not an XMID
				warning("Expected 'XMID' but found '%c%c%c%c'", pos[0], pos[1], pos[2], pos[3]);
				return false;
			}
			pos += 4;

		}

		// Ok it's an XMIDI.
		// We're going to identify and store the location for each track.
		if (_num_tracks > ARRAYSIZE(_tracks)) {
			warning("Can only handle %d tracks but was handed %d", (int)ARRAYSIZE(_tracks), (int)_num_tracks);
			return false;
		}

		int tracks_read = 0;
		while (tracks_read < _num_tracks) {
			if (!memcmp(pos, "FORM", 4)) {
				// Skip this plus the 4 bytes after it.
				pos += 8;
			} else if (!memcmp(pos, "XMID", 4)) {
				// Skip this.
				pos += 4;
			} else if (!memcmp(pos, "TIMB", 4)) {
				// Custom timbres?
				// We don't support them.
				// Read the length, skip it, and hope there was nothing there.
				pos += 4;
				len = read4high(pos);
				pos += (len + 1) & ~1;
			} else if (!memcmp(pos, "EVNT", 4)) {
				// Ahh! What we're looking for at last.
				_tracks[tracks_read] = pos + 8; // Skip the EVNT and length bytes
				pos += 4;
				len = read4high(pos);
				pos += (len + 1) & ~1;
				++tracks_read;
			} else {
				warning("Hit invalid block '%c%c%c%c' while scanning for track locations", pos[0], pos[1], pos[2], pos[3]);
				return false;
			}
		}

		// If we got this far, we successfully established
		// the locations for each of our tracks.
		// Note that we assume the original data passed in
		// will persist beyond this call, i.e. we do NOT
		// copy the data to our own buffer. Take warning....
		_ppqn = 60;
		resetTracking();
		setTempo(500000);
		_inserted_delta = 0;
		setTrack(0);
		return true;
	}

	return false;
}
Example #15
0
bool MidiParser::jumpToTick(uint32 tick, bool fireEvents) {
	if (_active_track >= _num_tracks)
		return false;

	Tracker currentPos(_position);
	EventInfo currentEvent(_next_event);

	resetTracking();
	_position._play_pos = _tracks[_active_track];
	parseNextEvent(_next_event);
	if (tick > 0) {
		while (true) {
			EventInfo &info = _next_event;
			if (_position._last_event_tick + info.delta >= tick) {
				_position._play_time += (tick - _position._last_event_tick) * _psec_per_tick;
				_position._play_tick = tick;
				break;
			}

			_position._last_event_tick += info.delta;
			_position._last_event_time += info.delta * _psec_per_tick;
			_position._play_tick = _position._last_event_tick;
			_position._play_time = _position._last_event_time;

			if (info.event == 0xFF) {
				if (info.ext.type == 0x2F) { // End of track
					_position = currentPos;
					_next_event = currentEvent;
					return false;
				} else {
					if (info.ext.type == 0x51 && info.length >= 3) // Tempo
						setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
					if (fireEvents)
						_driver->metaEvent(info.ext.type, info.ext.data, (uint16) info.length);
				}
			} else if (fireEvents) {
				if (info.event == 0xF0) {
					if (info.ext.data[info.length-1] == 0xF7)
						_driver->sysEx(info.ext.data, (uint16)info.length-1);
					else
						_driver->sysEx(info.ext.data, (uint16)info.length);
				} else
					_driver->send(info.event, info.basic.param1, info.basic.param2);
			}

			parseNextEvent(_next_event);
		}
	}

	if (!_smartJump || !currentPos._play_pos) {
		allNotesOff();
	} else {
		EventInfo targetEvent(_next_event);
		Tracker targetPosition(_position);

		_position = currentPos;
		_next_event = currentEvent;
		hangAllActiveNotes();

		_next_event = targetEvent;
		_position = targetPosition;
	}

	_abort_parse = true;
	return true;
}
Example #16
0
void MainWindow::startClock()
{
    isTracking = true;
    setTrayIconTrackingMode();
    resetTracking();
}