Пример #1
0
void CALLBACK Win32MidiIn::midiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
	Q_UNUSED(dwParam2);

	SynthRoute *synthRoute = (SynthRoute *)dwInstance;

	LPMIDIHDR pMIDIhdr = (LPMIDIHDR)dwParam1;
	if (wMsg == MIM_LONGDATA) {
		if (pMIDIhdr->dwBytesRecorded == 0) {
			// 0 length means returning the buffer to the application when closing
			return;
		}
		synthRoute->pushMIDISysex((BYTE *)pMIDIhdr->lpData, pMIDIhdr->dwBytesRecorded, MasterClock::getClockNanos());

		//	Add SysEx Buffer for reuse
		if (midiInAddBuffer(hMidiIn, pMIDIhdr, sizeof(MIDIHDR)) != MMSYSERR_NOERROR) {
			QMessageBox::critical(NULL, "Win32MidiIn Error", "Failed to add SysEx Buffer for reuse");
			return;
		}
		return;
	}
	if (wMsg == MIM_DATA) synthRoute->pushMIDIShortMessage(dwParam1, MasterClock::getClockNanos());
}
Пример #2
0
void SMFProcessor::run() {
	MidiSession *session = driver->createMidiSession(QFileInfo(fileName).fileName());
	SynthRoute *synthRoute = session->getSynthRoute();
	const MidiEventList &midiEvents = parser.getMIDIEvents();
	midiTick = parser.getMidiTick();
	quint32 totalSeconds = estimateRemainingTime(midiEvents, 0);
	MasterClockNanos startNanos = MasterClock::getClockNanos();
	MasterClockNanos currentNanos = startNanos;
	for (int i = 0; i < midiEvents.count(); i++) {
		const MidiEvent &e = midiEvents.at(i);
		currentNanos += e.getTimestamp() * midiTick;
		while (!stopProcessing && synthRoute->getState() == SynthRouteState_OPEN) {
			if (bpmUpdated) {
				bpmUpdated = false;
				totalSeconds = (currentNanos - startNanos) / MasterClock::NANOS_PER_SECOND + estimateRemainingTime(midiEvents, i + 1);
			}
			if (driver->seekPosition > -1) {
				SMFProcessor::sendAllNotesOff(synthRoute);
				MasterClockNanos seekNanos = totalSeconds * driver->seekPosition * MasterClock::NANOS_PER_MILLISECOND;
				MasterClockNanos eventNanos = currentNanos - e.getTimestamp() * midiTick - startNanos;
				if (seekNanos < eventNanos) {
					i = 0;
					eventNanos = 0;
					midiTick = parser.getMidiTick();
					emit driver->tempoUpdated(0);
				}
				i = seek(synthRoute, midiEvents, i, seekNanos, eventNanos) - 1;
				currentNanos = MasterClock::getClockNanos();
				startNanos = currentNanos - seekNanos;
				break;
			}
			emit driver->playbackTimeChanged(MasterClock::getClockNanos() - startNanos, totalSeconds);
			MasterClockNanos delay = currentNanos - MasterClock::getClockNanos();
			if (driver->fastForwardingFactor > 1) {
				MasterClockNanos timeShift = delay - (delay / driver->fastForwardingFactor);
				delay -= timeShift;
				currentNanos -= timeShift;
				startNanos -= timeShift;
			}
			if (delay < MasterClock::NANOS_PER_MILLISECOND) break;
			usleep(((delay < MAX_SLEEP_TIME ? delay : MAX_SLEEP_TIME) - MasterClock::NANOS_PER_MILLISECOND) / MasterClock::NANOS_PER_MICROSECOND);
		}
		if (stopProcessing || synthRoute->getState() != SynthRouteState_OPEN) break;
		if (driver->seekPosition > -1) {
			driver->seekPosition = -1;
			continue;
		}
		switch (e.getType()) {
			case SHORT_MESSAGE:
				synthRoute->pushMIDIShortMessage(e.getShortMessage(), currentNanos);
				break;
			case SYSEX:
				synthRoute->pushMIDISysex(e.getSysexData(), e.getSysexLen(), currentNanos);
				break;
			case SET_TEMPO: {
				uint tempo = e.getShortMessage();
				midiTick = parser.getMidiTick(tempo);
				emit driver->tempoUpdated(MidiParser::MICROSECONDS_PER_MINUTE / tempo);
				break;
			}
			default:
				break;
		}
	}
	SMFProcessor::sendAllNotesOff(synthRoute);
	emit driver->playbackTimeChanged(0, 0);
	qDebug() << "SMFDriver: processor thread stopped";
	driver->deleteMidiSession(session);
	if (!stopProcessing) emit driver->playbackFinished();
}