# Problem writing a MIDI file

**URL:** <https://forum.juce.com/t/problem-writing-a-midi-file/36031>\
**Category:** General JUCE discussion\
**Created:** [November 6, 2019, 11:36am UTC](https://forum.juce.com/t/problem-writing-a-midi-file/36031 "2019-11-06T11:36:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AAR](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@AAR](https://forum.juce.com/u/AAR)\
**Post date:** [November 6, 2019, 11:36am UTC](https://forum.juce.com/t/problem-writing-a-midi-file/36031/1 "2019-11-06T11:36:43Z")

</div>

Hello everyone, this is my first topic in the forum, first of all thank you for your help and your time in advance.  
After following the tutorial Create MIDI data ([https://docs.juce.com/master/tutorial\_midi\_message.html](https://docs.juce.com/master/tutorial_midi_message.html)) I wanted to try to code a simple program for writing MIDI messages into a local file, as I need to implement this in a bigger program.  
The code is the following:

```
#include "../JuceLibraryCode/JuceHeader.h"

static String getMidiMessageDescription(const MidiMessage& m)
{
	if (m.isNoteOn()) return "Note on " + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3);
	if (m.isNoteOff()) return "Note off " + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3);
	if (m.isProgramChange()) return "Program change " + String(m.getProgramChangeNumber());
	if (m.isPitchWheel()) return "Pitch wheel " + String(m.getPitchWheelValue());
	if (m.isAftertouch()) return "After touch " + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3) + ": " + String(m.getAfterTouchValue());
	if (m.isChannelPressure()) return "Channel pressure " + String(m.getChannelPressureValue());
	if (m.isAllNotesOff()) return "All notes off";
	if (m.isAllSoundOff()) return "All sound off";
	if (m.isMetaEvent()) return "Meta event";

	if (m.isController())
	{
		String name(MidiMessage::getControllerName(m.getControllerNumber()));

		if (name.isEmpty())
			name = "[" + String(m.getControllerNumber()) + "]";

		return "Controller " + name + ": " + String(m.getControllerValue());
	}

	return String::toHexString(m.getRawData(), m.getRawDataSize());
}
//==============================================================================
int main (int argc, char* argv[])
{

	//Messsage Generation
	int midiChannel = 10;
	double startTime= Time::getMillisecondCounterHiRes() * 0.001;
	int c3 = 60;
	MidiMessage message = MidiMessage::noteOn(1, c3, (uint8)100);
	message.setTimeStamp(Time::getMillisecondCounterHiRes() * 0.001 - startTime);
	std::wcout<< getMidiMessageDescription(message) << std::endl;
	MidiMessage messageOff = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber());
	messageOff.setTimeStamp(message.getTimeStamp() + 0.5);
	std::wcout << getMidiMessageDescription(messageOff) << std::endl;

	//MIDIFile and MidiMessageSequenceObject
	MidiFile midiFile;
	MidiMessageSequence mmSeq;
	//Adding MIDI Messages to MidiMessageSequence
	mmSeq.addEvent(message, 0);
	mmSeq.addEvent(messageOff, 0);
	//Adding MidiMessageSequence to MIDI file
	midiFile.addTrack(mmSeq);
	//Writing all to the outputStream
	File file("D:/JUCEProjects/PruebaGenMidi/prueba.mid");
	FileOutputStream stream(file);
	if (midiFile.writeTo(stream, 1)) {
		std::cout << "WriteTo method->true\n";
	}
	else {
		std::cout << "WriteTo method->false\n";
	}
	stream.flush();
    return 0;
}

```

As you can see, it is very simple and make use of the getMidiMessageDescription from the tutorial. After executing the program I get the following output in the console:  
Note on C3  
Note off C3  
WriteTo method-\>true  
The problem comes when I try to open this file with any DAW, altough the writeTo method returns true. In Ableton I cannot even put the prueba.mid in a MIDI Channel. In Reaper when I drag the file I get the following MIDI notes:

 ![MIDIFileProblem](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/3/3841b9b96b256e5b69a84f8cf33d0718ef74df27.png)

Does someone knows how to solve this issue?  
Thanks in advance,  
Andrés

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [November 6, 2019, 3:54pm UTC](https://forum.juce.com/t/problem-writing-a-midi-file/36031/2 "2019-11-06T15:54:16Z")

</div>

If you’re not already, you should be aware of:

[https://docs.juce.com/develop/classMidiMessage.html#a868d95a096fad999de5ba11f9a2f6340](https://docs.juce.com/develop/classMidiMessage.html#a868d95a096fad999de5ba11f9a2f6340)

```auto
String MidiMessage::getDescription	( )	const
Returns a human-readable description of the midi message as a string, for example "Note On C#3 Velocity 120 Channel 1".

```

Second, you need to use this function:

[https://docs.juce.com/develop/classMidiFile.html#ab18143cad013db21a71735b01aef2a9f](https://docs.juce.com/develop/classMidiFile.html#ab18143cad013db21a71735b01aef2a9f)

i’m just not sure where in the order of adding tracks to the `MidiFile` that it goes, if it’s before or after you add the `MidiMessageSequence`. But I know you need to make use of it.

---

<div class="post-metadata">

**Author:** ![AAR](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@AAR](https://forum.juce.com/u/AAR)\
**Post date:** [November 6, 2019, 10:16pm UTC](https://forum.juce.com/t/problem-writing-a-midi-file/36031/3 "2019-11-06T22:16:23Z")

</div>

Thanks for the response, I didn’t know that I had to use the setTicksPerQuarterNote() method.  
Finally I’ve been able to write the file. If anyone is interesed this is the code I tried for writing a chord (also messing around with sending each MidiOff message at a different time) into a MIDI File:

```
  int main (int argc, char* argv[])
 {
//Messsage Generation
int midiChannel = 10;
double startTime= Time::getMillisecondCounterHiRes() * 0.001;
int c3 = 60;
MidiMessage message = MidiMessage::noteOn(1, c3, (uint8)100);
message.setTimeStamp(Time::getMillisecondCounterHiRes() * 0.001 - startTime);
//Extra noteOn
MidiMessage message1 = MidiMessage::noteOn(1, c3+7, (uint8)100);
message1.setTimeStamp(message.getTimeStamp());
MidiMessage messageOff = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber());
//If 96 ticks per quarter note then 192 are 2 beats
messageOff.setTimeStamp(message.getTimeStamp() + 192);
//Extra noteOff
MidiMessage messageOff1 = MidiMessage::noteOff(message1.getChannel(), message1.getNoteNumber());
messageOff1.setTimeStamp(message1.getTimeStamp() + 96);

//MIDIFile and MidiMessageSequenceObject
MidiFile midiFile;
MidiMessageSequence mmSeq;
//Adding MIDI Messages to MidiMessageSequence
mmSeq.addEvent(message, 0);
mmSeq.addEvent(message1, 0);
mmSeq.addEvent(messageOff, 0);
mmSeq.addEvent(messageOff1, 0);
//Adding extra messages:

//Adding MidiMessageSequence to MIDI file	

midiFile.addTrack(mmSeq);	
midiFile.setTicksPerQuarterNote(96);

//Writing all to the outputStream
File file("D:/JUCEProjects/PruebaGenMidi/prueba.mid");
FileOutputStream stream(file);
if (midiFile.writeTo(stream, 1)) {
	std::cout << "WriteTo method->true\n";
}
else {
	std::cout << "WriteTo method->false\n";
}
stream.flush();
return 0;

```

}

---

<div class="post-metadata">

**Author:** ![vijayiyer](https://avatars.discourse-cdn.com/v4/letter/v/dbc845/32.png) [@vijayiyer](https://forum.juce.com/u/vijayiyer)\
**Post date:** [August 8, 2022, 6:12pm UTC](https://forum.juce.com/t/problem-writing-a-midi-file/36031/4 "2022-08-08T18:12:36Z")

</div>

For me, even setting the TIcksPerQuarterNote didn’t work.
