Click here to Skip to main content
14,606,272 members

Welcome to the Lounge

   

For discussing anything related to a software developer's life but is not for programming questions. Got a programming question?

The Lounge is rated Safe For Work. If you're about to post something inappropriate for a shared office environment, then don't post it. No ads, no abuse, and no programming questions. Trolling, (political, climate, religious or whatever) will result in your account being removed.
 
GeneralRe: Wooo! I did it Pin
David O'Neil1-Jul-20 10:41
professionalDavid O'Neil1-Jul-20 10:41 
GeneralRe: Wooo! I did it Pin
honey the codewitch1-Jul-20 14:28
mvahoney the codewitch1-Jul-20 14:28 
GeneralRe: Wooo! I did it Pin
David O'Neil1-Jul-20 14:36
professionalDavid O'Neil1-Jul-20 14:36 
GeneralRe: Wooo! I did it Pin
honey the codewitch1-Jul-20 15:01
mvahoney the codewitch1-Jul-20 15:01 
GeneralRe: Wooo! I did it Pin
David O'Neil1-Jul-20 15:58
professionalDavid O'Neil1-Jul-20 15:58 
GeneralRe: Wooo! I did it Pin
honey the codewitch1-Jul-20 17:05
mvahoney the codewitch1-Jul-20 17:05 
GeneralRe: Wooo! I did it Pin
David O'Neil1-Jul-20 20:40
professionalDavid O'Neil1-Jul-20 20:40 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 0:21
mvahoney the codewitch2-Jul-20 0:21 
i didn't mean true realtime. I just meant realtime enough for MIDI. I know Windows is not a realtime OS.

And anyway, that app isn't the problem. Like I said, the timing of it is solid and I can verify that.

The other app - the receiver is the problem.

This is the routine. Note that the only code that executes on incoming time sync messages is the if block with this heading:
if (0!=_tempoSynchEnabled && 0xF8 == (0xFF & lparam))


That will evaluate to true when it's one of these messages and the rest of the code does not execute.

I cannot speed this up.


void _MidiInProc(IntPtr handle, int msg, int instance, int lparam, int wparam)
{
	switch (msg)
	{
		case MIM_OPEN:
			Opened?.Invoke(this, EventArgs.Empty);
			break;
		case MIM_CLOSE:
			Closed?.Invoke(this, EventArgs.Empty);
			break;
		case MIM_DATA:
			MidiMessage m;
			if (0!=_tempoSynchEnabled && 0xF8 == (0xFF & lparam))
			{
				if (0 != _timingTimestamp)
				{
					var dif = (_PreciseUtcNowTicks - _timingTimestamp) * 24;
					var tpm = TimeSpan.TicksPerMillisecond * 60000;
					var newTempo = (tpm / (double)dif);
					if (newTempo < _tempoSynchMininumTempo)
						Interlocked.Exchange(ref _timingTimestamp, 0);
					else
					{
						var timeNow = _PreciseUtcNowTicks;

						if (0L==_tempoSyncTimestamp || 0L == _tempoSyncFrequency || (timeNow-_tempoSyncTimestamp>_tempoSyncFrequency))
						{
							var tmp = Tempo;
							var ta = (tmp + newTempo) / 2;
							Tempo = ta;
						}
						Interlocked.Exchange(ref _timingTimestamp, timeNow);
					}
				}
				else
				{
					var timeNow = _PreciseUtcNowTicks;
					Interlocked.Exchange(ref _timingTimestamp, timeNow);
				}
						
			}
			else
			{
				m = MidiUtility.UnpackMessage(lparam);
				_ProcessRecording(m);
				Input?.Invoke(this, new MidiInputEventArgs(new TimeSpan(0, 0, 0, 0, wparam), m));
			}
			break;
		case MIM_ERROR:
			Error?.Invoke(this, new MidiInputEventArgs(new TimeSpan(0, 0, 0, 0, wparam), MidiUtility.UnpackMessage(lparam)));
			break;
		case MIM_LONGDATA:
		case MIM_LONGERROR:
			// TODO: Semi tested
			var hdr = (MIDIHDR)Marshal.PtrToStructure(new IntPtr(lparam), typeof(MIDIHDR));
			if (0 == hdr.dwBytesRecorded)
				return; // no message
			// this code assumes it's a sysex message but I should probably check it.
			var status = Marshal.ReadByte(hdr.lpData, 0);
			var payload = new byte[hdr.dwBytesRecorded - 1];
			Marshal.Copy(new IntPtr((int)hdr.lpData + 1), payload, 0, payload.Length);
			m = new MidiMessageSysex(payload);
			var sz = Marshal.SizeOf(typeof(MIDIHDR));
			_inHeader.dwBufferLength = _inHeader.dwBytesRecorded = 65536u;
			_inHeader.lpData = _buffer;
			_CheckOutResult(midiInPrepareHeader(_handle, ref _inHeader, sz));
			_CheckOutResult(midiInAddBuffer(_handle, ref _inHeader, sz));
			_ProcessRecording(m);
			if (MIM_LONGDATA == msg)
				Input?.Invoke(this, new MidiInputEventArgs(new TimeSpan(0, 0, 0, 0, wparam),m));
			else
				Error?.Invoke(this, new MidiInputEventArgs(new TimeSpan(0, 0, 0, 0, wparam),m));
			break;
		case MIM_MOREDATA:
			break;
		default:
			break;
	}
}

Real programmers use butterflies

GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 8:21
professionalDavid O'Neil2-Jul-20 8:21 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 8:48
mvahoney the codewitch2-Jul-20 8:48 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 8:54
professionalDavid O'Neil2-Jul-20 8:54 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 9:07
mvahoney the codewitch2-Jul-20 9:07 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 9:10
professionalDavid O'Neil2-Jul-20 9:10 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 9:38
mvahoney the codewitch2-Jul-20 9:38 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 9:12
professionalDavid O'Neil2-Jul-20 9:12 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 9:36
mvahoney the codewitch2-Jul-20 9:36 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 10:10
professionalDavid O'Neil2-Jul-20 10:10 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 12:25
mvahoney the codewitch2-Jul-20 12:25 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 13:03
professionalDavid O'Neil2-Jul-20 13:03 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 13:18
mvahoney the codewitch2-Jul-20 13:18 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 9:10
mvahoney the codewitch2-Jul-20 9:10 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 9:15
professionalDavid O'Neil2-Jul-20 9:15 
GeneralRe: Wooo! I did it Pin
honey the codewitch2-Jul-20 9:33
mvahoney the codewitch2-Jul-20 9:33 
GeneralRe: Wooo! I did it Pin
David O'Neil2-Jul-20 10:12
professionalDavid O'Neil2-Jul-20 10:12 
GeneralRe: Wooo! I did it Pin
Greg Utas2-Jul-20 0:25
professionalGreg Utas2-Jul-20 0:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.