Help convert MidiTimeStamp from milliSeconds to Ticks

I am trying to take MidiEvents from the handleIncomingMidiMessage (MidiInput *source, const MidiMessage &message) and convert the timeStamps in to ticks so I can save it in a MIDIFile. “startTime” is just calculated when recording is started with (startTime = (Time::getMillisecondCounterHiRes() * .001);).

I’m also confused how to correctly change the timeStamp since the MidiMessage is const? I would also like to alter the miciChannel number, but I’m stuck for the same reason

[code]void PerformerManagerComponent::handleIncomingMidiMessage (MidiInput *source, const MidiMessage &message)
const int timeStamp = (int)((message.getTimeStamp() - startTime) * Time::getHighResolutionTicksPerSecond());

if(recState == true && playState == true)
	for (int i = 0; i < enabledMidiInputChannels.size(); i++)
		if(source->getName() == enabledMidiInputChannels[i])
			MidiMessage* const newOne = new MidiMessage (message);
			newOne->setTimeStamp (timeStamp);
			DBG( String("Message: chn: ") + String(newOne->getChannel())
				+ String(" Note: ") + String(newOne->getNoteNumber() )
				+ String(" Vel: ") + String(newOne->getVelocity() )
				+ String(" T: ") + String(newOne->getTimeStamp()) ); 


The midi file makes the notes, but the time relationship is all weird. I tried to use this thread as a starting point

Which had me setting up the MidiSequencers in there like this

                // grab the BPM and add it to the XML file or however we are going to do this
		int microsecondsperquarter = 60.0*Time::getHighResolutionTicksPerSecond()/120;

		for(int i = 0; i < midiSeqences.size(); i++)
			midiSeqences[i]->addEvent(MidiMessage::timeSignatureMetaEvent(4, 4));
1 Like

For anyone interested

I am currently trying to record data to a MIDI File in JUCE using an external clock source and having trouble. Here is a basic breakdown of the tricky bits

1)The midiCallback returns MidiMessages in seconds (with millisecond resolution). So message.getTimeStamp() returns a double that looks like 1234567.786
2)The tempoMetaEvent() requires an int that == the microseconds per quater note
3)setTicksPerQuarterNote(96) is what a MidiFile needs to understand time and is == to 96 ticks per quarter note
4)Time::getHighResolutionTicksPerSecond() == 1000000000 ( although I imagine it might change? it doesn’t seem to)
5)MidiClock == 24 clocks per quarter note

// find our startTime in seconds with millisecond resolution
startTime = (Time::getMillisecondCounterHiRes() * .001);

// find our microsecondsPerQuarter based off Tempo
microsecondsPerQuarter = 60.0*Time::getHighResolutionTicksPerSecond()/120; //120 is the BPM

//find our microsecondsPerQuarter based off the last two incoming midiClocks
double scaler = 24000000000.00;
microsecondsPerQuarter = (scaler * (message.getTimeStamp() - previousMessageStamp));
previousMessageStamp = message.getTimeStamp();

//find our midiMessage timeStamp in ticks based off the startTime (why do I need the .01??? arghh. I just messed around with the value till it worked, but that is ugly)
const int timeStamp = (int)(((message.getTimeStamp() - startTime)/(microsecondsPerQuarter * .01)) * Time::getHighResolutionTicksPerSecond());

1 Like