MidiPacketMBS.TimeStamp as MemoryBlock

Hello @Christian_Schmitz

If make some test with MBS Midi plugin on Mac. I want to send a note off some milliseconds after the note on. I already understand how to create a memory block for sending note on and note off (dataNoteOn, and dataNoteOff).

Is packet.timeStamp is the way to put some delay between note on and note off packet ? What kind of value may I use for timeStamp ?

// Add Packet to Packets 
packet.datamemory = dataNoteOn
packet.timeStamp = nil   //now
packets.append packet

On MBS website I read

m=newmemoryblock(8)
m.Long(0) = 2345678 // some time value
m.Long(4) = 3456789
pack = new MIDIPacketMBS
pack.TimeStamp = m

What 2345678 and 3456789 value represents ?

Thanks

That is just a dummy value.

From Apple documentation:

The time at which the events occurred, if receiving MIDI, or, if sending MIDI, the time at which the events are to be played. Zero means “now.” The time stamp applies to the first MIDI byte in the packet.

and

@typedef MIDITimeStamp

@abstract A host clock time.

@discussion

A host clock time representing the time of an event, as returned by

mach_absolute_time() or UpTime().

And for the current time, we have a “CurrentTime as UInt64” function there.
So you can add time to that.

Sorry @Christian_Schmitz I don’t understand what you say

Can you give me a solution to set pack.TimeStamp 500ms after now ?

Something like:

dim x as UInt64 = MidiPacketMBS.CurrentTime
dim y as UInt64 = MidiPacketMBS.NanosecondsToAbsolute(500000)

m=newmemoryblock(8)
m.Uint64Value(0) = x+y
pack = new MIDIPacketMBS
pack.TimeStamp = m

Like this maybe?

Thank you @Christian_Schmitz , this my code for now.

If I look midi messages with Midi Monitor. The two message are send at same time :smiling_face_with_tear:

Do you have any idea what’s wrong on my code

Var packetNoteOn As MIDIPacketMBS = New MIDIPacketMBS
Var packedListNoteOn As MIDIPacketListMBS = New MIDIPacketListMBS
Var packetsNoteOn(-1) As MIDIPacketMBS
Var dataNoteOn As MemoryBlock = New MemoryBlock(3)

Var packetNoteOff As MIDIPacketMBS = New MIDIPacketMBS
Var packedListNoteOff As MIDIPacketListMBS = New MIDIPacketListMBS
Var packetsNoteOff(-1) As MIDIPacketMBS
Var dataNoteOff as memoryBlock = New MemoryBlock(3)

Var m As MemoryBlock = New memoryblock(8)
Var now As UInt64 = MidiPacketMBS.CurrentTime
Var delay As UInt64 = MidiPacketMBS.NanosecondsToAbsolute(500000)

// Note ON
// --------

// Time Stamp
m.Uint64Value(0) = now

// Data
dataNoteOn.byte(0) = &h90 // Note On
dataNoteOn.byte(1) = 60 // Note Number
dataNoteOn.byte(2) = 127 // Velocity

// Add packetNoteOn to Packets 
packetNoteOn.DataMemory = dataNoteOn
packetNoteOn.timeStamp = m
packetsNoteOn.append packetNoteOn

If Not packedListNoteOn.FillList(packetsNoteOn) Then
  System.DebugLog("Something wrong on note On")
End

// Send packet
MNMMidiClient.Send(MNMMidiOutPort, MNMMidiDestination, packedListNoteOn)

// Note Off
// ---------

// Time Stamp
m.Uint64Value(0) = now + delay

// Data
dataNoteOff.byte(0) =  &h80 // Note Off
dataNoteOff.byte(1) = 60 // Note Number
dataNoteOff.byte(2) = 0 // Velocity

// Add packetNoteOff to Packets 
packetNoteOff.DataMemory = dataNoteOff
packetNoteOff.timeStamp = m
packetsNoteOff.append packetNoteOff

if not packedListNoteOff.FillList(packetsNoteOff) then
  msgBox "bad"
end


// Send packet
MNMMidiClient.Send(MNMMidiOutPort, MNMMidiDestination, packedListNoteOff)

I already try to change the 500000 value and packetNoteOn.timeStamp = nil. That’s produced the same things

I also try with a unique MidiClient.Send call and I got the same result

Var packedListNote As MIDIPacketListMBS = New MIDIPacketListMBS
Var midiPackets(-1) As MIDIPacketMBS

Var packetNoteOn As MIDIPacketMBS = New MIDIPacketMBS
Var packetNoteOff As MIDIPacketMBS = New MIDIPacketMBS

Var dataNoteOn As MemoryBlock = New MemoryBlock(3)
Var dataNoteOff as memoryBlock = New MemoryBlock(3)

Var m As MemoryBlock = New memoryblock(8)
Var now As UInt64 = MidiPacketMBS.CurrentTime
Var delay As UInt64 = MidiPacketMBS.NanosecondsToAbsolute(500000)


// Note ON
// --------

// Data
dataNoteOn.byte(0) = &h90 // Note On
dataNoteOn.byte(1) = 60 // Note Number
dataNoteOn.byte(2) = 127 // Velocity

// Add packetNoteOn to Packets 
packetNoteOn.DataMemory = dataNoteOn
packetNoteOn.timeStamp = nil // Now
midiPackets.append packetNoteOn

If Not packedListNote.FillList(midiPackets) Then
  System.DebugLog("Something wrong on note On")
End

// Send packet
//MNMMidiClient.Send(MNMMidiOutPort, MNMMidiDestination, packedListNote)

// Note Off
// ---------

// Time Stamp
m.Uint64Value(0) = now + delay

// Data
dataNoteOff.byte(0) =  &h80 // Note Off
dataNoteOff.byte(1) = 60 // Note Number
dataNoteOff.byte(2) = 0 // Velocity

// Add packetNoteOff to Packets 
packetNoteOff.DataMemory = dataNoteOff
packetNoteOff.timeStamp = m
midiPackets.append packetNoteOff

if not packedListNote.FillList(midiPackets) then
  msgBox "bad"
end

// Send packet
MNMMidiClient.Send(MNMMidiOutPort, MNMMidiDestination, packedListNote)

Could you try timeStampValue as Uint64 instead of using memory block?

I try this with the same result :sob:

// Note Off
// ---------

// Time Stamp
Var i As UInt64 = now + delay
System.DebugLog("n: " + now .ToString+ ", d:" + delay.ToString + ", i: " + i.ToString)


// Data
dataNoteOff.byte(0) =  &h80 // Note Off
dataNoteOff.byte(1) = 60 // Note Number
dataNoteOff.byte(2) = 0 // Velocity

// Add packetNoteOff to Packets 
packetNoteOff.DataMemory = dataNoteOff
packetNoteOff.TimeStampValue = i
midiPackets.append packetNoteOff

Console output is

n: 37672449131928, d:12000, i: 37672449143928

Unsolvable problem may be a MBS Plugin Bug

I may check here later to see if Midi Monitor just doesn’t show the time stamp or it is not sent.

1 Like

I got it working. Please note that 500 ms in nanoseconds require three more zeros.

Dim pack As MIDIPacketMBS
dim list as MIDIPacketListMBS
Dim packs(-1) As MIDIPacketMBS
Dim num As Integer
Dim data As memoryBlock


list = New MIDIPacketListMBS

pack = New MIDIPacketMBS
data = NewMemoryBlock(3)


Var now As UInt64 = MidiPacketMBS.CurrentTime
data.Byte(0) = &h90    'note on
data.Byte(1) = noteValue + 48  'take it up a few octaves
data.Byte(2) = &h7C    'velocity
pack.datamemory = data
pack.timeStampValue = now
System.DebugLog "TimeStampValue: "+pack.TimeStampValue.ToString

packs.append pack

pack = New MIDIPacketMBS
data = NewMemoryBlock(3)

data.Byte(0) = &h80    'note off
data.Byte(1) = noteValue + 48  'take it up a few octaves
data.byte(2) = &h7C    'velocity
pack.datamemory = data

Var delay As UInt64 = MidiPacketMBS.NanosecondsToAbsolute(500000000)
pack.TimeStampValue = now + delay


System.DebugLog "delay: "+delay.ToString
System.DebugLog "TimeStampValue: "+pack.TimeStampValue.ToString

packs.append pack
if not list.FillList(packs) then
  msgBox "bad"
end

client.Send(outport, currentDest, list)

Also I decided to send both commands in our send call. Please try.

Hello @Christian_Schmitz

Your solution create message with correct timestamp value but it doesn’t do what I expected. If I look on MidiMonitor the two notes are send at the same moment. It’s not what I want.

Maybe the timestampvalue is not the correct approach.

I need to send a note on and a note off with a small delay. As you Midi is asynchronous and with some Midi devices with a long wire to secure data transmission I need to but 500ms between to events.

I think I must create a stack go message and mange it by myself

For me it shows a 500ms delay in Midi Monitor.

Did you try my code to send them both with both having time stamps?

and a Screenshot:

And don’t have the same result

I just look on MidiMonitor preference and I change this property

Now I can see the time stamp delay of 500 ms

Unfortunately this is not the result I expected. If I record the midi signal into a sequencer like Ableton Live I should see a 500ms note. This is not the case.

If I launch from Ableton Live a note that lasts 500ms here is what I see in MidiMonitor.


This is the result I was hoping for !

I think the TimeStamp property has more to do with MIDI timing clocks than it does with the length of a note determined by the time between the NoteOn and NoteOff messages.

What do you think ?